linux 进程间通信——信号

#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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值