Linux 信号量
程序员文章站
2022-07-13 16:44:11
...
需求:如何实现fork()后的子进程退出后,再退出父进程
#include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> int main() { pid_t result; int sem_id; result=fork(); if(result==-1) { perror("fork\n"); }else if(result==0) { printf("chind process wait for some seconds ...\n"); sleep(5); printf("The returned value is %d in the child process(pid=%d)\n",result,getpid()); }else{ //int status; //wait(status); printf("The return value is %d in the father process(pid=%d)\n",result,getpid()); } return 0; }
上述代码,明显父进程先于子进程前退出
解决方案一: 在父进程中调用 wait() 方法,堵塞等待子进程退出
解决方案二: 利用信号量同步进程退出顺序.
#include <sys/types.h> #include <sys/ipc.h> #include <sys/sem.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> // 当semctl参数为4个时,必须手动定义这个联合体 union semun { int val; struct semid_ds *buf; unsigned short *array; struct seminfo *_buf; }; // 初始化信号量 int init_sem(int sem_id,int init_value) { union semun sem_union; sem_union.val=init_value; if(semctl(sem_id,0,SETVAL,sem_union)==-1) { perror("init semphore"); return -1; } return 0; } // 删除信号量 int del_sem(int sem_id) { union semun sem_union; if(semctl(sem_id,0,IPC_RMID,sem_union)==-1) { perror("delete semphore"); return -1; } return 0; } // p操作获取资源 int sem_p(int sem_id) { struct sembuf sem_b; sem_b.sem_num = 0; // 单个信号量 sem_b.sem_op = -1; // -1表p操作 sem_b.sem_flg=SEM_UNDO; // 在进程退出时,自动释放信号量 if(semop(sem_id,&sem_b,1)==-1) { perror("p operation"); return -1; } return 0; } // v操作释放资源 int sem_v(int sem_id) { struct sembuf sem_b; sem_b.sem_num = 0; // 信号量编号, 单个信号量 sem_b.sem_op = 1; // +1表V操作 sem_b.sem_flg=SEM_UNDO; // 在进程退出时,自动释放信号量 if(semop(sem_id,&sem_b,1)==-1) { perror("v operation"); return -1; } return 0; } int main(int argc,char **argv) { pid_t result; int sem_id; // key_t key=ftok() 产生唯一ipc键 sem_id=semget(ftok(".",'a'),1,0666|IPC_CREAT); init_sem(sem_id,0); // 设置信号量为0 result=fork(); if(result==-1) { perror("fork\n"); }else if(result==0) // 子进程 { printf("chind process wait for some seconds ...\n"); sleep(5); printf("The returned value is %d in the child process(pid=%d)\n",result,getpid()); sem_v(sem_id); // v操作,资源数+1 }else{ // 父进程 sem_p(sem_id); // 此时资源计数为0,堵塞等待子进程释放资源,当资源数>0时才向下执行 printf("The return value is %d in the father process(pid=%d)\n",result,getpid()); sem_v(sem_id); del_sem(sem_id); } return 0; }
详见: http://blog.csdn.net/mybelief321/article/details/9086151
上一篇: Block的简单使用
下一篇: Flutter之网络编程与数据存储