免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 551 | 回复: 1
打印 上一主题 下一主题

关于多进程同步问题求助 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-07-31 10:18 |只看该作者 |倒序浏览
程序产生两个进程,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 %d\n",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);
}


现在产生两个很麻烦的问题,第一:父进程无法等待所有子进程退出后就自己退出了!第二:信号量第一次创建后,程序退出在重启动后报错,信号量已经存在!也就是这个程序无法自己释放信号量!

请问这些问题如何解决呢??伤脑筋啊!~~~

论坛徽章:
0
2 [报告]
发表于 2006-08-01 13:12 |只看该作者
1. signal函数是edge triggered吧,在信号的处理函数中截获到信号后,如果不重新设置该信号的处理函数,系统就会设置成系统默认的处理函数。
2. 信号量的可以设置成让程序退出系统就自动释放的。man一下吧。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP