linux c 进程的实现,Linuxc - 进程竞争条件

本文详细介绍了Linux环境下如何处理进程间的竞争条件,通过使用waitpid、getppid等条件轮询以及信号实现进程间的同步。同时,还展示了使用管道来实现进程间的通信。这些方法有效避免了并发执行时数据的不一致性问题。
摘要由CSDN通过智能技术生成

linuxc-进程竞争条件

当多个进程都企图对共享数据进行某种处理,而最后的结果又取决于进程运行的顺序时,我们认为发生了竞争条件(race condition)。

详情见《unix环境高级编程》8.9小节

解决方法:

waitpid、getppid等条件轮询

进程间通讯,主要实现TELL_WAIT、TELL_PARENT、WAIT_PARENT、TELL_CHILD、WAIT_CHILD5个函数。

code

信号实现

见《unix环境高级编程》10.16

#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");

}

管道实现

见《unix环境高级编程》15.2

#include "apue.h"

static int pfd1[2], pfd2[2];

void

TELL_WAIT(void)

{

if (pipe(pfd1) < 0 || pipe(pfd2) < 0)

err_sys("pipe error");

}

void

TELL_PARENT(pid_t pid)

{

if (write(pfd2[1], "c", 1) != 1)

err_sys("write error");

}

void

WAIT_PARENT(void)

{

char c;

if (read(pfd1[0], &c, 1) != 1)

err_sys("read error");

if (c != 'p')

err_quit("WAIT_PARENT: incorrect data");

}

void

TELL_CHILD(pid_t pid)

{

if (write(pfd1[1], "p", 1) != 1)

err_sys("write error");

}

void

WAIT_CHILD(void)

{

char c;

if (read(pfd2[0], &c, 1) != 1)

err_sys("read error");

if (c != 'c')

err_quit("WAIT_CHILD: incorrect data");

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值