本文主要参考《unix环境高级编程》
竞争条件:当多个进程都企图对共享数据进行某种处理,而最后的结果又取决于进程运行的顺序时,则我们认为这发生了竞争条件。可能出现的情况看下面代码:
见书186程序清单8-6(我在我电脑试过,好像没有产生竞争意外结果,可能电脑速度太快了吧)
一个进程希望等待一个子进程终止,则它必须调用一种wait函数。
一个进程希望等待一个父进程终止,则它可以采用下面的轮询方式:(可是轮询方式浪费CPU时间)
while (getppid() != 1) sleep(1);
|
为了避免竞争条件和轮询方式,可以使用信号机制,或者使用各种形式的进程间通信(IPC).
下面是通过信号机制解决问题的,相关的信号函数可以参看“信号”一部分。
1 #include "apue.h" 2 3 static void competition(char *); 4 5 int main(void) 6 { 7 pid_t pid; 8 9 TELL_WAIT(); 10 11 if((pid=fork()) < 0) { 12 err_sys("fork error"); 13 } else if (pid == 0) { 14 WAIT_PARENT(); //let father go first
15 competition("output from child\n"); 16 } else { 17 competition("output from parent\n"); 18 TELL_CHILD(pid); 19 } 20 exit(0); 21 } 22 23 static void competition(char *str) 24 { 25 char *ptr; 26 int c; 27 setbuf(stdout, NULL); 28 for (ptr=str; (c=*ptr++) != 0;) 29 putc(c,stdout); 30 }
|
上面的程序还是有bug的,比如shell命令 ./a.out;./a.out;./a.out
上面的命令可能使得输出变乱,因为父进程结束后,会继续下一个shell命令,这个新的命令和原来没有完成的子进程之间有竞争条件。
再修改一下代码应该如下:
也就是父进程完成任务后,等等子进程,等到子进程也完成任务后,自己再退出。
1 #include "apue.h" 2 3 static void competition(char *); 4 5 int main(void) 6 { 7 pid_t pid; 8 9 TELL_WAIT(); 10 11 if((pid=fork()) < 0) { 12 err_sys("fork error"); 13 } else if (pid == 0) { 14 WAIT_PARENT(); //let father go first
15 competition("output from child\n"); 16 TELL_PARENT(getppid()); 17 } else { 18 competition("output from parent\n"); 19 TELL_CHILD(pid); 20 WAIT_CHILD(); 21 } 22 exit(0); 23 } 24 25 static void competition(char *str) 26 { 27 char *ptr; 28 int c; 29 setbuf(stdout, NULL); 30 for (ptr=str; (c=*ptr++) != 0;) 31 putc(c,stdout); 32 }
|
阅读(673) | 评论(0) | 转发(0) |