zoukankan      html  css  js  c++  java
  • Linux下的信号量学习

    转:http://www.360doc.com/content/11/0114/14/1317564_86488642.shtml#


    #include<stdio.h>
    #include<sys/types.h>
    #include<sys/ipc.h>
    #include<sys/sem.h>
    #include<stdlib.h>
    #include<math.h>
    #include<errno.h>
    int main()
    {
        int pid,val,semid;//中者为可用资源数量,后者为信号灯(即信号量)集的识别代号
        key_t semkey;
        if((semkey=ftok("./test.c",1))<0)//将文件路径和项目ID(后面那个“1“)转换为System V IPC Key
        {
            printf("ftok函数转换出现错误。 ");
            exit(1);
        }
        else
            printf("ftok函数转换成功,key值为%d ",semkey);
        if((semid=semget(semkey,1,IPC_CREAT|IPC_EXCL|0700))<0)//创建信号灯集,其中包含1个信号灯
        {
            printf("semget函数创建信号灯集出现错误。 ");
            exit(2);
        }
        else
            printf("semget函数创建信号灯集成功,信号灯集识别代号semid为:%d ",semid);
        val=1;
        if((semctl(semid,0,SETVAL,val))<0)//此句与上句合起来的功能是将semid对应的信号集中的第一个信号(0表示第一个信号)的可用资源数量设置为1
        {
            printf("semctl函数设置可用资源数量时出现错误。 ");
            exit(9);
        }
        else
            printf("semctl函数设置可用资源数量成功。 ");
        if((pid=fork())<0)
        {
            printf("fork函数创建子进程出现错误。 ");
            exit(3);
        }
        else if(pid>0)//父进程,先索取共享资源,而后释放
        {
            struct sembuf p_op_buf,v_op_buf;
            printf("父进程ID为:%d,该进程将要索取共享资源 ",getpid());
            p_op_buf.sem_num=0;
            p_op_buf.sem_op=-1;
            if(semop(semid,&p_op_buf,1)<0)//以上三行向semid代表的信号灯集的第一个信号灯申请一个资源
            {
                printf("父进程中,semop函数索取共享资源出现错误。 ");
                exit(4);
            }
            else
            {
                int i;
                printf("父进程中,semop函数索取共享资源成功,索取个数为:%d ",abs(p_op_buf.sem_op));
                printf("ID为%d的父进程现在要睡上6秒钟。 ",getpid());
                for(i=6;i>0;i--)
                {
                    printf("%d号进程(父进程)还要睡%d秒钟…… ",getpid(),i);
                    sleep(1);
                }
                printf("%d号进程(父进程)已经醒来,并将释放资源。 ",getpid());
                v_op_buf.sem_num=0;
                v_op_buf.sem_op=1;
                p_op_buf.sem_flg=0;//该标志位此处不清零不会出现错误,但下面子进程中的该标志位应清零,因为那时父进程已经占据了资源,子进程申 请不到资源的情况下,该标志位如果不清零(比如采用不赋值的默认处理),可能会出现错误。
                if(semop(semid,&v_op_buf,1)<0)//以上三行将释放一个资源给semid代表的信号灯集第一个信号灯
                {
                    printf("父进程中,semop函数索取共享资源出现错误。 ");
                    exit(5);
                }
                else
                {
                    printf("ID号为%d的父进程中,semop函数释放共享资源成功,释放个数为:%d ",getpid(),v_op_buf.sem_op);
                    sleep(1);
                }
            }
        }
        else//子进程不断申请共享资源,申请到后声明一下,然后释放
        {
            struct sembuf p_op_buf,v_op_buf;
            sleep(2);//等待父进程将唯一的资源占用
            printf("子进程ID为:%d,该进程将要索取共享资源 ",getpid());
            p_op_buf.sem_num=0;
            p_op_buf.sem_op=-1;
            p_op_buf.sem_flg=0;//该标志位不用要清零,此处不清零将出现错误
            if(semop(semid,&p_op_buf,1)<0)//向semid代表的信号灯集的第一个信号灯申请一个资源,申请不到就一直在这儿等着,什么时候有了资源,什么时候接着向下进行
            {
                printf("子进程中,semop函数索取共享资源出现错误:%d ",errno);
                exit(6);
            }
            else
                printf("**********子程序已经成功申请到资源!********** ");
            v_op_buf.sem_num=0;
            v_op_buf.sem_op=1;
            if(semop(semid,&v_op_buf,1)<0)//以上三行将释放一个资源给semid代表的信号灯集第一个信号灯
            {
                printf("子进程中,semop函数索取共享资源出现错误。 ");
                exit(7);
            }
            else
            {
                printf("子进程中,semop函数释放共享资源成功,释放个数为:%d ",v_op_buf.sem_op);
                printf("ID号为%d的进程(子进程)退出! ",getpid());
                if(semctl(semid,0,IPC_RMID,0)<0)
                {
                    printf("调用semctl删除信号量集出现错误。 ");
                    exit(8);
                }
                else
                {
                    printf("识别代号为%d的信号量集已经被删除 ",semid);
                    exit(0);
                }
            }
        }
    }
    /*********************程序运行结果*********************
    [admin@localhost temp]$ ./sem
    ftok函数转换成功,key值为16802469
    semget函数创建信号灯集成功,信号灯集识别代号semid为:393216
    semctl函数设置可用资源数量成功。
    父进程ID为:4062,该进程将要索取共享资源
    父进程中,semop函数索取共享资源成功,索取个数为:1
    ID为4062的父进程现在要睡上6秒钟。
    4062号进程(父进程)还要睡6秒钟……
    4062号进程(父进程)还要睡5秒钟……
    子进程ID为:4063,该进程将要索取共享资源(但此时唯一的资源被父进程所占据,因此一直在此等待资源被释放)
    4062号进程(父进程)还要睡4秒钟……
    4062号进程(父进程)还要睡3秒钟……
    4062号进程(父进程)还要睡2秒钟……
    4062号进程(父进程)还要睡1秒钟……
    4062号进程(父进程)已经醒来,并将释放资源。
    ID号为4062的父进程中,semop函数释放共享资源成功,释放个数为:1
    **********子程序已经成功申请到资源!**********(父进程释放资源后,刚才曾经提出申请的子进程就可以申请到资源了)
    子进程中,semop函数释放共享资源成功,释放个数为:1
    ID号为4063的进程(子进程)退出!
    识别代号为393216的信号量集已经被删除
    ***********************************************************/

  • 相关阅读:
    ElasticSearch记录(1)底层原理
    hbase学习记录(4)hbase和Hadoop整合(实现wrodcount程序)
    flume记录(2)监控文件和目录,对hdfs操作
    flume记录(1)使用
    hbase学习记录(3)JAVA_API操作hbase
    hbase学习记录(2)shell常用命令
    hbase学习记录(1)简介
    ssh三大框架整合
    spring事务管理
    Ubuntu 18.04版本设置root账户
  • 原文地址:https://www.cnblogs.com/yinsua/p/3218662.html
Copyright © 2011-2022 走看看