linux进程间同步
在stevens大师的书中看到如下代码:
#include "apue.h"
static void charatatime(char *);
int main()
{
   pid_t pid;    
   TELL_WAIT();    
   if((pid = fork()) < 0)
   {
     err_sys("fork error");
   }
   else if(pid == 0)
   {
     WAIT_PARENT();
     charatatime("output from child\n");
   }
   else
   {
     charatatime("output from parent\n");
     TELL_CHILD(pid);
   }
   exit(0);
}
static void charatatime(char *str)
{
   char *ptr;
   int c;
   setbuf(stdout, NULL);
   for(ptr = str; (c = *ptr++) != 0;)
     putc(c, stdout);
}  
其中TELL_WAIT、WAIT_PARENT、TELL_CHILD在另外一个文件tellwait.c中,被编译成lib文件,如下:
#include "apue.h"
static volatile sig_atomic_t sigflag; /* set nonzero by sig handler */
static sigset_t newmask, oldmask, zeromask;
static void
sig_usr(int signo)	/* one signal handler for SIGUSR1 and SIGUSR2 */
{
	sigflag = 1;
}
void
TELL_WAIT(void)
{
	if (signal(SIGUSR1, sig_usr) == SIG_ERR)
		err_sys("signal(SIGUSR1) error");
	if (signal(SIGUSR2, sig_usr) == SIG_ERR)
		err_sys("signal(SIGUSR2) error");
	sigemptyset(&zeromask);
	sigemptyset(&newmask);
	sigaddset(&newmask, SIGUSR1);
	sigaddset(&newmask, SIGUSR2);
	/*
	 * Block SIGUSR1 and SIGUSR2, and save current signal mask.
	 */
	if (sigprocmask(SIG_BLOCK, &newmask, &oldmask) < 0)
		err_sys("SIG_BLOCK error");
}
void
TELL_PARENT(pid_t pid)
{
	kill(pid, SIGUSR2);		/* tell parent we're done */
}
void
WAIT_PARENT(void)
{
	while (sigflag == 0)
		sigsuspend(&zeromask);	/* and wait for parent */
	sigflag = 0;
	/*
	 * Reset signal mask to original value.
	 */
	if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
		err_sys("SIG_SETMASK error");
}
void
TELL_CHILD(pid_t pid)
{
	kill(pid, SIGUSR1);			/* tell child we're done */
}
void
WAIT_CHILD(void)
{
	while (sigflag == 0)
		sigsuspend(&zeromask);	/* and wait for child */
	sigflag = 0;
	/*
	 * Reset signal mask to original value.
	 */
	if (sigprocmask(SIG_SETMASK, &oldmask, NULL) < 0)
		err_sys("SIG_SETMASK error");
}
我想问的是,tellwait.c中的sigflag是父子进程共享的吗?链接库难道父子进程共享吗?链接库不是采用写时复制机制吗?求高手指点迷津啊。。。。
------解决方案--------------------
信号啊,共享个屁啊。
父进程kill信号给子进程,子进程信号函数标记变量,sigsuspend被唤醒检查变量满足,于是子进程开始执行。
父进程在kill信号之后开始等待子进程给它kill信号,同样是sigprocmask +sigsuspend的等待,子进程kill信号给父进程,父进程sigsuspend被唤醒检查变量被设置于是程序结束。
这个编程方法和条件变量+互斥量是完全一样的:
pthread_mutex_lock == sigprocmask
pthread_cond_wait ==  sigsuspend
pthread_cond_signal == kill
pthread_mutex_unlock == sigprocmask
加锁/阻塞信号 是为了在检查变量时是线程安全的, 而sigsuspend/cond_wait是保证解锁/解信号阻塞与挂起等待是原子的, 这样才能保证不漏掉信号/条件的唤醒.