linux 进程间通信——信号

来源:互联网 发布:mac怎么修改登录密码 编辑:程序博客网 时间:2024/05/17 12:02
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include "error_exit.h" 

static volatile sig_atomic_t sigflag;
static sigset_t new_mask, old_mask, zero_mask;

static void sig_usr(const int signo)
{
sigflag = 1;
}

//进程信号同步前的准备
void tell_wait()
{
if (signal(SIGUSR1, sig_usr) == SIG_ERR)
 error_exit("signal SIGUSR1 error");
if (signal(SIGUSR2, sig_usr) == SIG_ERR)
 error_exit("signal SIGUSR2 error");

sigemptyset(&zero_mask);
sigemptyset(&new_mask);
sigaddset(&new_mask, SIGUSR1);
sigaddset(&new_mask, SIGUSR2);

//阻塞SIGUSR1和SIGUSR2,保存当前信号阻塞状态
if (sigprocmask(SIG_BLOCK, &new_mask, &old_mask) < 0)
 error_exit("sigprocmask error");
}

void tell_parent(pid_t pid)
{
kill(pid, SIGUSR2);  //向父进程发送SIGUSR2信号
}

void wait_parent()
{
while (sigflag == 0)
 sigsuspend(&zero_mask);  //等待父进程
sigflag = 0;

if (sigprocmask(SIG_SETMASK, &old_mask, NULL) < 0)
 error_exit("sigprocmask reset error");
}

void tell_child(pid_t pid)
{
kill(pid, SIGUSR1);  //向子进程发送SIGUSR1信号
}

void wait_child()
{
while (sigflag == 0)
 sigsuspend(&zero_mask);  //等待子进程
sigflag = 0;

if (sigprocmask(SIG_SETMASK, &old_mask, NULL) < 0)
 error_exit("sigprocmask reset error");
}

void print_char(char *str)
{
char *ptr;
int c;

setbuf(stdout, NULL);
for (ptr = str; (c = *ptr++) != 0;)
{
putc(c, stdout);
usleep(0.1);
}
}

int main(int argc, char *argv[])
{
pid_t pid;
tell_wait();

if ((pid = fork()) < 0)
 error_exit("fork error");
else if (pid == 0)
{
print_char("output from child\n");
tell_parent(getppid());
}
else
{
wait_child();
print_char("output from parent\n");
}

return 0;
}
0 0
原创粉丝点击