Linux_4.6_信号量互斥编程



 (1) 信号量:


(2) 信号量分类



(3)首先来说说key

    key用来唯一标识文件(等)的数字


  制定键值:



(4) 函数说明

    

8.1创建/打开信号量集合

8.1.1 函数名

semget

8.1.2 函数原形

int semget(key_t key,int nsems,int semflg);

8.1.3 函数功能

获取信号量集合的标识符

当key指定的信号量不存在的时候,并且semfleg里面包含了

IPC_CREAT,这个时候,就会创建一个信号量集合.

8.1.4 所属头文件

#include<sys/types.h>

#include<sys/sem.h>

#include <sys/ipc.h>

8.1.5 返回值

成功:返回信号量集合的标识符

失败:返回-1

8.1.6 参数说明

key: 键值

nsems:创建的这个信号量集合里面包含的信号量数目

semflg:标志,可以取IPC_CREAT.


 

8.2操作信号量

8.2.1 函数名

semop

8.2.2 函数原形

int semop(int semid,struct sembuf*sops,unsigned nsops)

8.2.3 函数功能

操作信号量集合里面的信号量

8.2.4 所属头文件

#include<sys.types.h>

#include<sys/ipc.h>

#include<sys/sem.h>

8.2.5 返回值

成功:返回0

失败:返回-1

8.2.6 参数说明

semid:要操作的信号量集合的标识符

sops:对信号量执行什么样的操作

nsops:要操作多少个信号量


sembuf结构体说明:

 struct  sembuf{
         unsigned short        s em_num;      //信号在信号集中的索引,0代表第一个信号,1代表第二个信号  
         short            sem_op;      //操作类型
         short            sem_flg;    //操作标志
     };


  • sem_op 参数:
     sem_op > 0    信号加上 sem_op 的值,表示进程释放控制的资源;

     sem_op = 0    如果没有设置 IPC_NOWAIT,则调用进程进入睡眠状态,直到信号                                    量的值为0;否则进程不回睡眠,直接返回 EAGAIN

     sem_op < 0    信号加上 sem_op 的值。若没有设置 IPC_NOWAIT ,则调用进程阻
              塞,直到资源可用;否则进程直接返回EAGAIN
  • sem_flg 参数
  该参数可设置为 IPC_NOWAIT 或 SEM_UNDO 两种状态。只有将 sem_flg 指定为 SEM_UNDO 标志后,semadj (所指定信号量针对调用进程的调整值)才会更新。   此外,如果此操作指定SEM_UNDO,系统更新过程中会撤消此信号灯的计数(semadj此操作可以随时进行---它永远不会强制等待过程调用进程必须有改变信号量集权限
  sem_flg公认标志是 IPC_NOWAIT 和 SEM_UNDO如果操作指定SEM_UNDO将会自动撤消该进程终止

  在标准操作程序操作数组的顺序执行、原子的,那就是,该操作要么作为一个完整的单元,要么如果不是所有操作都可以立即执行的系统调用行为取决于个人sem_flg领域IPC_NOWAIT标志存在


 对信号量最基本的操作就是进行PV操作,而System V信号量正是通过 semop 函数和 sembuf 结构体的数据结构来进行PV操作的。

 当 sembuf 的第二个数据结构 sem_op 设置为负数时,是对它进行P操作,即减1操作;当设置为正数时,就是进行V操作,即加1操作。

 P和V是来源于两个荷兰语词汇,

 P—— passeren,中文译为"通过";

 V—— vrijgeven,中文译为"释放"。


函数名:

ftok()

头文件

#include <sys/types.h>

#include <sys/ipc.h>

函数原型:

 key_t  ftok( const  char * pathname , int   proj_id  );


函数功能:

 该函数把从pathname导出的信息与id的低序8位组合成一个整数IPC键。


参数:

 pathname 就时你指定的文件名(该文件必须是存在而且可以访问的),id是子序号,虽         然为int,但是只有8个比特被使用(0-255)。

返回值: 成功时候返回key_t 类型的key值,失败返回-1


semctl函数:

点击打开链接


(5) 实例:公告板问题(student1向公告板写"class math is cancle",student2向公告板写"english exam")

设置信号量初始值为1;在student1写入时,将信号量1,变为0;此时student2写入时,会等待student1执行完毕.反之亦然!

student1.c文件:

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>

int main(void)
{
    int fd = 0;
    key_t key;
    int semid;
    struct sembuf sops;

    int ctl;

    /*create key*/
    key = ftok("/home",1);

    /** create or open semaphore set*/
    semid = semget(key,1,IPC_CREAT);

   /* GETVAL:get init value of sem*/
    //ctl = semctl(semid,0,GETVAL);
    /*SETVAL: set init value of sem to 1*/
    semctl(semid,0,SETVAL,1);
    ctl = semctl(semid,0,GETVAL);
    printf("init value of sem is %d\n",ctl);

    /*1. open file*/
    fd =  open("./board.txt",O_RDWR|O_APPEND);

    /** get semaphore set*/
    sops.sem_num = 0;
    sops.sem_op = -1;

    semop(semid,&sops,1);
    /*2. write "class math" to notice file*/
    write(fd,"class math",11);

    /*3. pause*/
    sleep(10);

/*4. write "cancle" to notice file*/
    write(fd,"is cancle",10);

    /** release semaphore*/
    sops.sem_num = 0;
    sops.sem_op = +1;

    semop(semid,&sops,1);

    close(fd);

    return 0;

}


student2.c文件

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <stdio.h>

int main(void)
{
    int fd = 0;
    key_t key;
    int semid;
    struct sembuf sops;
    int ctl;

    /*create key*/
    key = ftok("/home",1);

    /*open semaphore set*/
    semid = semget(key,1,IPC_CREAT);

//
    ctl = semctl(semid,0,GETVAL);

    printf("init value of sem is %d\n",ctl);

    /*1. open notice file*/
    fd = open("./board.txt",O_RDWR|O_APPEND);

    /*get semaphore set*/
    sops.sem_num = 0;
    sops.sem_op = -1;
    semop(semid,&sops,1);


    /*2. write "english exam"*/
    write(fd,"english exam",20);


    /*release semaphore*/
    sops.sem_num = 0;
    sops.sem_op = +1;
    semop(semid,&sops,1);

    /*3. close notice file*/
    close(fd);

    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值