IO进程——信号灯集

目录

1.信号灯集

1.1概念

1.2操作步骤

1.3函数接口

1.3.1创建或打开信号灯集

1.3.2初始化或删除信号灯集

1.3.3 pv操作

1.4操作命令


1.信号灯集

1.1概念

信号灯(semaphore),也叫信号量。它是不同进程间或一个给定进程内部不同线程间同步的机制;

System V信号灯集是一个或者多个信号灯的一个集合。其中的每一个都是单独的计数信号灯。而Posix信号灯指的是单个计数信号灯。

通过信号灯集实现共享内存的同步操作

1.2操作步骤

1.创建key值

2.创建或打开信号灯集

3.初始化信号灯集

4.pv操作

5.删除信号灯集

1.3函数接口

1.3.1创建或打开信号灯集

#include <sys/sem.h>

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

功能:创建/打开信号灯

参数:

        key:ftok产生的key值

        nsems:信号灯集中包含的信号灯数目

        semflg:信号灯集的访问权限,通常为IPC_CREAT |0666

返回值:

        成功:信号灯集ID

        失败:-1

出现这种情况就是semid等于0了

我们可以手动去删除这个信号灯集:

ipcs -s :查看创建的信号灯集

ipcrm -s [semid]:删除信号灯集

示例:

#include <stdio.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/types.h>
#include <errno.h>

int main()
{
    int semid;
    key_y key;
    key = ftok("./app", 'a');
    if(key < 0)
    {
        perror("ftok err");
        return -1;
    }

    semid = semget(key, 2, IPC_CREAT | IPC_EXCL | 0666);
    if(semid < 0)
    {
        if(errno == EEXIST)
            semid = semget(key, 2, 0666);
        else
        {
            perror("semget err");
            return -1;
        }
    }
    printf("%d\n",semid);
    return 0;
}

1.3.2初始化或删除信号灯集

int semctl ( int semid , int semnum , int cmd,… /*union semun arg*/ );

功能:信号灯集合的控制(初始化/删除)

参数:

        semid:信号灯集ID

        semnum: 要操作的集合中的信号灯编号

        cmd:

                GETVAL:获取信号灯的值,返回值是获得值

                SETVAL:设置信号灯的值,

                IPC_RMID:从系统中删除信号灯集合

                ...:当cmd为SETVAL时,需要传递共用体

返回值:

        成功 0

        失败 -1

共用体格式:

union semun

{

        int val; /* 信号量的初值 */

        struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */

        unsigned short *array; /* Array for GETALL, SETALL */

        struct seminfo *__buf; /* Buffer for IPC_INFO (Linux-specific) */

};

示例:

 

补充:

  1. 当cmd为SETVAL时需要传递第四个参数,类型为共用体,

用法:

union semun {

        int val;

};

union semun sem;

sem.val = 10;

semctl(semid, 0, SETVAL, sem); //对编号为0的信号灯设置初值为10

1.当cmd为IPC_RMID时,表示删除信号灯集

用法:semctl(semid, 0, IPC_RMID) // 0:表示信号灯的编号,指定任意一个即可删除

2.当cmd为GETVAL时,表示获取信号灯的值

用法:printf("%d\n", semctl(semid, 0, GETVAL));

1.3.3 pv操作

int semop ( int semid , struct sembuf * opsptr , size_t nops );

功能:对信号灯集合中的信号量进行PV操作

参数:

        semid:信号灯集ID

        opsptr:操作方式

        nops: 要操作的信号灯的个数 1

返回值:

        成功 :0

        失败:-1

struct sembuf {

        short sem_num; // 要操作的信号灯的编号

        short sem_op; // 0 : 等待,直到信号灯的值变成0

                                // 1 : 释放资源,V操作

                                // -1 : 分配资源,P操作

        short sem_flg; // 0(阻塞),IPC_NOWAIT, SEM_UNDO

};

示例:

 

使用:

申请资源 P操作:

mysembuf.sem_num = 0;

mysembuf.sem_op = -1;

mysembuf.sem_flg = 0;

semop(semid, &mysembuf, 1);

释放资源 V操作:

mysembuf.sem_num = 0;

mysembuf.sem_op = 1;

mysembuf.sem_flg = 0;

semop(semid, &mysembuf, 1);

封装函数:使代码更简洁美观

 示例:

1.4操作命令

ipcs -s :查看创建的信号灯集

ipcrm -s [semid]:删除信号灯集

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值