当前位置导航:炫浪网>>网络学院>>编程开发>>C++教程>>C++基础入门教程

关于IPC的一个小例子

    经常有人问IPC的问题,下面是一些简单的例子。有空看看!
    System V信号量
    [code:1:4e079536a0]
    #define PERMS S_IRUSR|S_IWUSR

    void init_semaphore_struct(struct sembuf *sem,int semnum,
    int semop,int semflg)
    {
    /* 初始话信号灯结构 */
    sem->sem_num=semnum;
    sem->sem_op=semop;
    sem->sem_flg=semflg;
    }

    int del_semaphore(int semid)
    {
    /* 信号灯并不随程序的结束而被删除,如果我们没删除的话(将1改为0)
    可以用ipcs命令查看到信号灯,用ipcrm可以删除信号灯的
    */
    #if 1
    return semctl(semid,0,IPC_RMID);
    #endif
    }

    int main(int argc,char **argv)
    {
    char buffer[MAX_CANON],*c;
    int i,n;
    int semid,semop_ret,status;
    pid_t childpid;
    struct sembuf semwait,semsignal;

    if((argc!=2)||((n=atoi(argv[1]))<1))
    {
    fprintf(stderr,"Usage:%s number\n\a",argv[0]);
    exit(1);
    }

    /* 使用IPC_PRIVATE 表示由系统选择一个关键字来创建 */
    /* 创建以后信号灯的初始值为0 */
    if((semid=semget(IPC_PRIVATE,1,PERMS))==-1)
    {
    fprintf(stderr,"[%d]:Acess Semaphore Error:%s\n\a",
    getpid(),strerror(errno));
    exit(1);
    }

    /* semwait是要求资源的操作(-1) */
    init_semaphore_struct(&semwait,0,-1,0);

    /* semsignal是释放资源的操作(+1) */
    init_semaphore_struct(&semsignal,0,1,0);

    /* 开始的时候有一个系统资源(一个标准错误输出) */
    if(semop(semid,&semsignal,1)==-1)
    {
    fprintf(stderr,"[%d]:Increment Semaphore Error:%s\n\a",
    getpid(),strerror(errno));
    if(del_semaphore(semid)==-1)
    fprintf(stderr,"[%d]:Destroy Semaphore Error:%s\n\a",
    getpid(),strerror(errno));
    exit(1);
    }

    /* 创建一个进程链 */
    for(i=0;i if(childpid=fork()) break;

    sprintf(buffer,"[i=%d]-->[Process=%d]-->[Parent=%d]-->[Child=%d]\n",
    i,getpid(),getppid(),childpid);
    c=buffer;

    /* 这里要求资源,进入原子操作 */
    while(((semop_ret=semop(semid,&semwait,1))==-1)&&(errno==EINTR));
    if(semop_ret==-1)
    {
    fprintf(stderr,"[%d]:Decrement Semaphore Error:%s\n\a",
    getpid(),strerror(errno));
    }
    else
    {
    while(*c!='\0')fputc(*c++,stderr);
    /* 原子操作完成,赶快释放资源 */
    while(((semop_ret=semop(semid,&semsignal,1))==-1)&&(errno==EINTR));
    if(semop_ret==-1)
    fprintf(stderr,"[%d]:Increment Semaphore Error:%s\n\a",
    getpid(),strerror(errno));
    }

    /* 不能够在其他进程反问信号灯的时候,我们删除了信号灯 */
    while((wait(&status)==-1)&&(errno==EINTR));
    /* 信号灯只能够被删除一次的 */
    if(i==1)
    if(del_semaphore(semid)==-1)
    fprintf(stderr,"[%d]:Destroy Semaphore Error:%s\n\a",
    getpid(),strerror(errno));
    exit(0);
    }
    [/code:1:4e079536a0]
    SystemV消息队列
    [code:1:4e079536a0]
    #define MSG_FILE "server.c"
    #define BUFFER 255
    #define PERM S_IRUSR|S_IWUSR

    struct msgtype {
    long mtype;
    char buffer[BUFFER+1];
    };

    int main()
    {
    struct msgtype msg;
    key_t key;
    int msgid;

    if((key=ftok(MSG_FILE,'a'))==-1)
    {
    fprintf(stderr,"Creat Key Error:%s\a\n",strerror(errno));
    exit(1);
    }

    if((msgid=msgget(key,PERM|IPC_CREAT|IPC_EXCL))==-1)
    {
    fprintf(stderr,"Creat Message Error:%s\a\n",strerror(errno));
    exit(1);
    }

    while(1)
    {
    msgrcv(msgid,&msg,sizeof(struct msgtype),1,0);
    fprintf(stderr,"Server Receive:%s\n",msg.buffer);
    msg.mtype=2;
    msgsnd(msgid,&msg,sizeof(struct msgtype),0);
    }
    exit(0);
    }


    --------------------------------------------------------------------------------

 

共3页 首页 上一页 1 2 3 下一页 尾页 跳转到
相关内容
赞助商链接