linux进程通信-信号量

信号灯

1.     信号量

(1)概念

信号量(又名:信号灯)与其他进程间通信方式不大相同,主要用途是保护临界资源.

进程可以根据它判定是否能够访问某些共享资源。除了用于访问控制外,还可用于进程同步。

(2)分类

二值信号灯:信号灯的值只能取0或1,类似于互斥锁。 但两者有不同:

信号灯强调共享资源,只要共享资源可用,其他进程同样可以修改信号灯的值;

互斥锁更强调进程,占用资源的进程使用完资源后,必须由进程本身来解锁。

   计数信号灯:信号灯的值可以取任意非负值

(3)步骤

a)       创建打开信号量,semget()

b)       初始化信号量,semctl()SETVAL操作。使用二维信号量时将信号量初始化为1;

c)       进行信号量的PV操作,调用semop()函数。

d)       如果不用信号量,从系统中删除他/她,使用semctl的IPC_RMID操作。

 

2.     内核实现信号灯的原理及其API函数

(1)semget

函数的作用:创建信号量

函数的原型:int semget(key_t key,int nsems,int semflg);

函数的参数:nsems:创建信号量的数目,通常取1个

            semflg:同open一样的权限

返回值:成功:信号量的标识符;出错:-1

(2)semctl

函数的作用:信号量的控制:初始化、删除等

函数的原型:int semctl(int semid,int semnum,int gmd,union semun arg);

函数的参数:semnum:通常为0,第一个信号量

            cmd:IPC_STAT:获取结构量

                IPC_SETVAL:设置为arg中的val值

                IPC_GETVAL:获取信号量的值

                IPC_RMID:从系统中删除信号量

            arg:union semun结构

返回值:cmd不同的返回值不同

    IPC_STAT、IPC_SETVAL、IPC_RMID、返回值为0;IPC_GETVAL:返回信号量的值;出错为-1

(3)semop

函数的作用:执行PV操作

函数的原型:int semop(int semid,struct sembuf * sops,size_t nsops);

函数的参数:semid:semget()函数返回的信号量标识符

            sops:指向信号量操作数组

            struct sembuf *sops;

            sem_op:-1为P操作;+1为V操作

            nsops:操作信号量的个数

返回值:成功:信号量标识符;出错:-1

 

3.     如何使用信号灯来实现进程间的同步与互斥?

信号量的同步和互斥PV(见下例)

sem1.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/sem.h>

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

    key = ftok("/home/linux/", 1);
    semid = semget(key, 1, IPC_CREAT);

    ret = semctl(semid, 0, SETVAL, 1);
    fd = open("borad.txt", O_RDWR | O_CREAT | O_APPEND);
    sops.sem_num = 0;
    sops.sem_op = -1;
    semop(semid, &sops, 1);

    write(fd, "class math", 11);

    sleep(20);
    sops.sem_num = 0;
    sops.sem_op = +1;
    semop(semid, &sops, 1);
    close(fd);

    return 0;
}


sem2.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/ipc.h>
#include <sys/sem.h>

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

    key = ftok("/home/linux/", 1);
    semid = semget(key, 1, IPC_CREAT);

    fd = open("borad.txt", O_RDWR | O_CREAT | O_APPEND);
    sops.sem_num = 0;
    sops.sem_op = -1;
    semop(semid, &sops, 1);

    write(fd, "class math", 11);

    sleep(20);
    sops.sem_num = 0;
    sops.sem_op = +1;
    semop(semid, &sops, 1);
    close(fd);

    return 0;
}
运行结果:



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值