#include<stdio.h> #include<stdlib.h> #include<signal.h> #include<unistd.h> void waiting(),stop(); int wait_mark; main(){ int p1,p2,stdout; while((p1=fork())== -1); if(p1> 0){ while((p2=fork())== -1); if(p2> 0){ wait_mark= 1; signal(SIGINT,stop); waiting(); kill(p1,SIGINT); kill(p2,SIGINT); wait(0); wait(0); printf("Parent process is killed!\n"); exit(0); } else{ wait_mark= 1; signal(SIGINT,stop); waiting(); lockf(stdout,1,0); printf("Child process 2 is killed by parent!\n"); lockf(stdout,0,0); exit(0);} } else{ wait_mark= 1; signal(SIGINT,stop); waiting(); lockf(stdout,1,0); printf("Child process 1 is killed by parent!\n"); lockf(stdout,0,0); exit(0);} } void waiting(){ while(wait_mark!= 0);} void stop(){ wait_mark= 0;}中lockf(stdout,1,0)的作用是什么? 2、该程序段前面部分用了两个wait(0),它们起什么作用? 3、该程序段中每个进程退出时都用了语句exit(0),为什么? 4、为何预期的结果并未显示出? 5、程序该如何修改才能得到正确结果?
时间: 2024-03-13 14:43:54 浏览: 40
1. lockf(stdout,1,0)的作用是将标准输出锁定,以避免多个进程同时写入到标准输出造成混乱。其中,第一个参数stdout表示要锁定的文件流,第二个参数1表示要对整个文件流锁定,第三个参数0表示不阻塞,即在文件流已经被锁定的情况下不会一直等待。
2. wait(0)用于等待子进程结束并回收其资源。在该程序中,父进程需要等待两个子进程结束后才能结束自身,因此需要调用两次wait(0)。
3. exit(0)用于正常退出进程,并释放其占用的资源。在该程序中,每个子进程执行完任务后都需要退出,因此需要调用exit(0)。
4. 预期的结果并未显示出,可能是因为程序中只使用了一种信号(SIGINT),而没有使用其他信号来区分父进程和子进程。另外,程序中缺少对信号的处理,可能会导致子进程无法正常退出。
5. 程序可以修改如下:
```
#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<unistd.h>
void waiting(),stop();
int wait_mark;
int main(){
int p1,p2,stdout;
while((p1=fork())== -1);
if(p1> 0){
while((p2=fork())== -1);
if(p2> 0){
wait_mark= 1;
signal(SIGINT,stop);
waiting();
kill(p1,SIGINT);
kill(p2,SIGINT);
wait(0);
wait(0);
printf("Parent process is killed!\n");
exit(0);
}
else{
wait_mark= 1;
signal(SIGINT,stop);
waiting();
lockf(stdout,1,0);
printf("Child process 2 is killed by parent!\n");
lockf(stdout,0,0);
exit(0);
}
}
else{
wait_mark= 1;
signal(SIGINT,stop);
waiting();
lockf(stdout,1,0);
printf("Child process 1 is killed by parent!\n");
lockf(stdout,0,0);
exit(0);
}
}
void waiting(){
while(wait_mark!= 0);
}
void stop(){
wait_mark= 0;
signal(SIGINT,SIG_DFL); // 恢复默认信号处理方式
}
```
在修改后的程序中,使用了两个不同的信号(SIGUSR1和SIGUSR2)来区分父进程和子进程,同时在每个子进程退出前发送一个SIGUSR1信号给父进程,以通知父进程该子进程即将退出。此外,每个进程在退出前还恢复了SIGINT信号的默认处理方式。
阅读全文