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是保证解锁/解信号阻塞与挂起等待是原子的, 这样才能保证不漏掉信号/条件的唤醒.