C语言实现父进程主动终止子进程的方法总结
作者:java 乐山
一般的情况,子进程自己运行完后,执行exit 或者return 后,父进程wait. waitpid收回子进程,但子进程是一个循环等待状态不主动退出,父进程可以采用文中介绍的几种方法,需要的朋友可以参考下
1.如子进程是循环状态
子进程循环等待键盘的输入,如父进程模拟键盘输入一个字符,子进程收到就跳出scanf()。同理,如是socket 的accept()等待,也可以发送一字符,让子进程跳出等待。
#include <string.h> #include <stdio.h> #include <fcntl.h> #include <linux/input.h> #include <linux/uinput.h> #include <stdio.h> #include <unistd.h> #include <wait.h> void mn_key(int fd,int kval) { struct input_event event; event.type = EV_KEY; event.value = 1; event.code = kval; write(fd,&event,sizeof(event)) ; event.type = EV_SYN; event.code = SYN_REPORT; event.value = 0; write(fd, &event, sizeof(event)); memset(&event, 0, sizeof(event)); event.type = EV_KEY; event.code = kval; event.value = 0; write(fd, &event, sizeof(event)); event.type = EV_SYN; event.code = SYN_REPORT; event.value = 0; write(fd, &event, sizeof(event)); } int main() { int stat; pid_t pid=fork(); if(pid==0){ while(1){ char c[20]; scanf("%s",c); if(!strcmp(c,"0")){ //接收到0字符,子进程退出 puts("zjc over"); return 0; } printf("zjc:%s\n",c); } } sleep(10); //10秒后,中止子进程的运行。 int fd = open("/dev/input/event3",O_RDWR); //每个机器的event(n)可能不同。 if(fd<=0){ puts("keyboad error"); //dev/input/event3 权限chmod 777 要能读写 return -1; } mn_key(fd,KEY_0); mn_key(fd,KEY_ENTER); mn_key(fd,KEY_ENTER); //不清楚为什麽要两行 wait(&stat); close(fd); }
2.上面的方法不通用,可以说是特例,下面的方法采用kill()函数,可以说是通用方法,采用管道先把子进程号传到父进程,再用kill函数。此方法非常暴力,直接杀死子进程,不管它是否结束。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #include <wait.h> #include <signal.h> #include <sys/prctl.h> #include <sys/types.h> int main(void){ // int stat; int zf[2]; pipe(zf); //此句必须放在fork()语句前 pid_t pid=fork(); if(pid==0){ pid_t pid1=getpid(); printf("z:%d\n",pid1); write(zf[1],&pid1,4); while(1){ char c[10]; scanf("%s",c); if(!strcmp(c,"~")){ puts("zjc over"); exit(0); } printf("%s\n",c); } } sleep(3); pid_t bz; read(zf[0],&bz,4); //父进程取得子进程号 printf("f:%d\n",bz); kill(bz,1); //关闭子进程 // wait(&stat); return 0; }
3. 父进程用sigqueue() 发送终止信号,子进程signal() 收到父进程信号,改变循环标志位,退出循环,再退出子进程。此种方法文明不粗暴。此处父进程不能用raise函数,因为此函数只能向本进程发送信号。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/socket.h> #include <wait.h> #include <sys/types.h> #include <signal.h> int main(void){ union sigval si; si.sival_int=0; int stat; pid_t zf[2]; pipe(zf); pid_t pid=fork(); if(pid==0){ pid_t id=getpid(); write(zf[1],&id,4); int t=1; void handle(int sig){ printf("%d\n",sig); t=0; } signal(20,&handle); while(t){ puts("zjc"); sleep(1); } printf("%d\n",t); //t=0 exit(0); } int bz; read(zf[0],&bz,4); sleep(2); sigqueue(bz,20,si); wait(&stat); return 0; }
sigqueue可以为非子进程的不关联进程发信号,只要知道对方的进程号就行了,可以用有名管道把进程号先传给对方进程。突然想到,可不可以用这个发信号的方法来执行进程间的互斥等操作。多进程主要用于多任务,比如需要同时运行两个以上执行动作的场景。
对于被安装信号的进程来讲,进程内代码执行与信号触发是异步的。信号好象是硬件的中断。条件产生了,操作系统就触发信号,执行信号的默认函数动作。执行完后,又继续执行进程的代码。
信号可以安装在一个进程内,再由本进程触发完成动作,如定时。
这个信号感觉非常有用,感觉这才是真正的多任务,进程间可以互不影响,一个进程完成某个动作后,触发信号通知另一个进程,(在触发信号之前,另一个进程可以干别的事情)。告诉它,我已完成,你可以怎么办。
以上就是C语言实现父进程主动终止子进程的方法总结的详细内容,更多关于C语言父进程终止子进程的资料请关注脚本之家其它相关文章!