关于多进程同步问题求助
程序产生两个进程,childA,childB两个进程分别使用管道进行通信,childA对管道写数据childB对管道读数据!父进程利用pause函数进入等待状态,然后利用signal来获取子进程的退出!代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/sem.h>
#define SEMPERM 0600 //信号量创建后的访问许可权
typedef union _semun{
int val;
struct semid_ds *buf;
ushort *array;
}semun;
typedef void Sigfunc(int);
int semids;
void childA(int *fd,int s_key)
{
int data = 1;
close(fd[0]);
for(;data < 20;data++){
p(s_key); //P操作
fprintf(stderr,"run child A %d n",data);
write(fd[1],(char*)&data,sizeof(int));
}
exit(1);
}
Sigfunc *signal(int singno,Sigfunc *func)
{
struct sigaction atc,oatc;
atc.sa_handler = func;
sigemptyset(&atc.sa_mask);
atc.sa_flags = 0;
if(sigaction(singno,&atc,&oatc) < 0)
return (SIG_ERR);
return (oatc.sa_handler);
}
Sigfunc *Signal(int signalno,Sigfunc *func)
{
Sigfunc *sigfunc;
if( (sigfunc = signal(signalno,func)) == SIG_ERR)
fprintf(stderr,"Signal error n");
return (sigfunc);
}
void childB(int *fd,int s_key)
{
int re_data = 1;
int a = 0;
fd_set reads;
close(fd[1]);
FD_ZERO(&reads);
FD_SET(fd[0],&reads);
while(a++ < 19){
select(fd[0]+1,&reads,NULL,NULL,NULL);
if(FD_ISSET(fd[0],&reads)){
read(fd[0],(char *)&re_data,sizeof(int));
fprintf(stderr,"Out data %d %dn",re_data,a);
sleep(a);
v(s_key); //v 操作
}
}
exit(2);
}
int initsem(key_t semkey) //创建并初始化信号量
{
int status = 0,semid;
if((semid = semget(semkey,1,SEMPERM|IPC_CREAT|IPC_EXCL)) == -1){
perror("Sem error n ");
if(errno == EEXIST)
semid = semget(semkey,1,0);
}else{
semun arg;
arg.val = 1;
status = semctl(semid,0,SETVAL,arg);
}
if(semid == -1 || status == -1){
perror("Init sem error n");
}
return semid;
}
int p(int semid)
{
struct sembuf p_buf;
p_buf.sem_num = 0;
p_buf.sem_op = -1;
p_buf.sem_flg = SEM_UNDO;
if(semop(semid,&p_buf,1) == -1){
perror("P(semid)faild");
exit(1);
}
return (0);
}
int v(int semid)
{
struct sembuf v_buf;
v_buf.sem_num = 0;
v_buf.sem_op = 1;
v_buf.sem_flg = SEM_UNDO;
if(semop(semid,&v_buf,1) == -1){
perror("V(semid failed ");
exit(1);
}
return (0);
}
static void sig_cld(int signo)
{
pid_t pid;
int status;
fprintf(stderr,"SIGCLD received n ");
while((pid = waitpid(-1,&status,WNOHANG)) > 0){ //等待子进程退出
//没有信号量操作时候可以成功等待所有子进程退出
printf("pid =%d n",pid);
}
}
int main()
{
int pipe_fd[2];
pid_t pid;
key_t skey;
skey = 0x1833;
pipe(pipe_fd);
semids = initsem(skey);
signal(SIGCHLD,sig_cld);
pid = fork();
if(pid == 0){
childB(pipe_fd,semids); //创建进程B
}
pid = -1;
pid = fork();
if(pid == 0){
childA(pipe_fd,semids); //创建进程A 先创建进程B进行读操作后创建进程A进行写操作
}
pause(); //等待状态
printf("parent out n");
exit(1);
}
现在产生两个很麻烦的问题,第一:父进程无法等待所有子进程退出后就自己退出了!第二:信号量第一次创建后,程序退出在重启动后报错,信号量已经存在!也就是这个程序无法自己释放信号量!
请问这些问题如何解决呢??伤脑筋啊!~~~
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
1. signal函数是edge triggered吧,在信号的处理函数中截获到信号后,如果不重新设置该信号的处理函数,系统就会设置成系统默认的处理函数。
2. 信号量的可以设置成让程序退出系统就自动释放的。man一下吧。