保护色无损:linux信号量编程

来源:百度文库 编辑:偶看新闻 时间:2024/04/20 09:08:42
上午和晚上花了些时间,匆忙把软考教程看完了第二遍。还有5天时间考试,预计要做4套卷子,包括两套模拟试题、06年和07年的真题,以及几年来的公共部分试题、其他公共部分模拟题等。另外,在做这些题不懂的时候,要对应复习教材上的内容。时间紧,任务重。

下午和晚上看了linux信号量的一些内容,有些复杂,有点晕。但总算是编写出了信号量相关的练习程序,并已经在机器上调试过了。现在把程序代码贴在下面:

/*********************程序相关信息*********************
程序编号:014
程序编写起始日期:2008.11.2
程序编写完成日期:2008.11.2
程序修改日期:                                   修改备注:
程序目的:学习linux信号量
所用主要函数:ftok(),semget(),semop(),semctl()
程序说明:在本机上运行时,可以把程序中的“./test.c”修改成自己机器上的某个文件(要带路径)
程序完成地点: 宿舍内
*********************程序相关信息*********************/
#include
#include
#include
#include
#include
#include
#include
int main()
{
    int pid,val,semid;//中者为可用资源数量,后者为信号灯(即信号量)集的识别代号
    key_t semkey;
    if((semkey=ftok("./test.c",1))<0)//将文件路径和项目ID(后面那个“1“)转换为System V IPC Key
    {
        printf("ftok函数转换出现错误。\n");
        exit(1);
    }
    else
        printf("ftok函数转换成功,key值为%d\n",semkey);
    if((semid=semget(semkey,1,IPC_CREAT|IPC_EXCL|0700))<0)//创建信号灯集,其中包含1个信号灯
    {
        printf("semget函数创建信号灯集出现错误。\n");
        exit(2);
    }
    else
        printf("semget函数创建信号灯集成功,信号灯集识别代号semid为:%d\n",semid);
    val=1;
    if((semctl(semid,0,SETVAL,val))<0)//此句与上句合起来的功能是将semid对应的信号集中的第一个信号(0表示第一个信号)的可用资源数量设置为1
    {
        printf("semctl函数设置可用资源数量时出现错误。\n");
        exit(9);
    }
    else
        printf("semctl函数设置可用资源数量成功。\n");
    if((pid=fork())<0)
    {
        printf("fork函数创建子进程出现错误。\n");
        exit(3);
    }
    else if(pid>0)//父进程,先索取共享资源,而后释放
    {
        struct sembuf p_op_buf,v_op_buf;
        printf("父进程ID为:%d,该进程将要索取共享资源\n",getpid());
        p_op_buf.sem_num=0;
        p_op_buf.sem_op=-1;
        if(semop(semid,&p_op_buf,1)<0)//以上三行向semid代表的信号灯集的第一个信号灯申请一个资源
        {
            printf("父进程中,semop函数索取共享资源出现错误。\n");
            exit(4);
        }
        else
        {
            int i;
            printf("父进程中,semop函数索取共享资源成功,索取个数为:%d\n",abs(p_op_buf.sem_op));
            printf("ID为%d的父进程现在要睡上6秒钟。\n",getpid());
            for(i=6;i>0;i--)
            {
                printf("%d号进程(父进程)还要睡%d秒钟……\n",getpid(),i);
                sleep(1);
            }
            printf("%d号进程(父进程)已经醒来,并将释放资源。\n",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函数索取共享资源出现错误。\n");
                exit(5);
            }
            else
            {
                printf("ID号为%d的父进程中,semop函数释放共享资源成功,释放个数为:%d\n",getpid(),v_op_buf.sem_op);
                sleep(1);
            }
        }
    }
    else//子进程不断申请共享资源,申请到后声明一下,然后释放
    {
        struct sembuf p_op_buf,v_op_buf;
        sleep(2);//等待父进程将唯一的资源占用
        printf("子进程ID为:%d,该进程将要索取共享资源\n",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\n",errno);
            exit(6);
        }
        else
            printf("**********子程序已经成功申请到资源!**********\n");
        v_op_buf.sem_num=0;
        v_op_buf.sem_op=1;
        if(semop(semid,&v_op_buf,1)<0)//以上三行将释放一个资源给semid代表的信号灯集第一个信号灯
        {
            printf("子进程中,semop函数索取共享资源出现错误。\n");
            exit(7);
        }
        else
        {
            printf("子进程中,semop函数释放共享资源成功,释放个数为:%d\n",v_op_buf.sem_op);
            printf("ID号为%d的进程(子进程)退出!\n",getpid());
            if(semctl(semid,0,IPC_RMID,0)<0)
            {
                printf("调用semctl删除信号量集出现错误。\n");
                exit(8);
            }
            else
            {
                printf("识别代号为%d的信号量集已经被删除\n",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的信号量集已经被删除
***********************************************************/