sem_id在linux,Linux sem信号量使用笔记

semget 函数为获取信号量函数

使用格式:

#include

int semget(key_t _key ,int _nsems,int _semflg);

功能:创建一个新的信号量或获取一个已经存在的信号量的键值。

返回值:成功返回信号量的标识码ID。失败返回-1;

参数:

_key为整型值,用户可以自己设定。有两种情况:

1. 键值是IPC_PRIVATE,该值通常为0,意思就是创建一个仅能被进程进程给我的信号量。

2. 键值不是IPC_PRIVATE,我们可以指定键值,例如1234;也可以一个ftok()函数来取得一个唯一的键值。

_nsems表示初始化信号量的个数。比如我们要创建一个信号量,则该值为1.,创建2个就是2。

_semflg:信号量的创建方式或权限。有IPC_CREAT,IPC_EXCL。

IPC_CREAT如果信号量不存在,则创建一个信号量,否则获取。

IPC_EXCL只有信号量不存在的时候,新的信号量才建立,否则就产生错误。

ipcs –s用来查看信号量。

如果需要从新建立键值是一样的信号量需要删除之前的信号量,新建的信号量才能起效。

semctl()控制信号量的函数

格式:

#include

int semctl(int _semid ,int _semnum,int

_cmd ……);

功能:控制信号量的信息。

返回值:成功返回0,失败返回-1;

参数:

_semid信号量的标志码(ID),也就是semget()函数的返回值;

_semnum,操作信号在信号集中的编号。从0开始。

_cmd命令,表示要进行的操作。

下面列出的这些命令来源于百度!

参数cmd中可以使用的命令如下:

IPC_STAT读取一个信号量集的数据结构semid_ds,并将其存储在semun中的buf参数中。

IPC_SET设置信号量集的数据结构semid_ds中的元素ipc_perm,其值取自semun中的buf参数。

IPC_RMID将信号量集从内存中删除。

GETALL用于读取信号量集中的所有信号量的值。

GETNCNT返回正在等待资源的进程数目。

GETPID返回最后一个执行semop操作的进程的PID。

GETVAL返回信号量集中的一个单个的信号量的值。

GETZCNT返回这在等待完全空闲的资源的进程数目。

SETALL设置信号量集中的所有的信号量的值。

SETVAL设置信号量集中的一个单独的信号量的值。

semop();信号来那个操作处理的函数

格式:#include

int semop(int  semid

,struct sembuf *_sops

,size_t _nsops);

功能:用户改变信号量的值。也就是使用资源还是释放资源使用权。

返回值:成功返回0,失败返回-1;

参数:

_semid :信号量的标识码。也就是semget()的返回值。

_sops是一个指向结构体数组的指针。

struct sembuf{

unsigned short sem_num;//第几个信号量,第一个信号量为0;

short sem_op;//对该信号量的操作。

short _semflg;

};

sem_num:操作信号在信号集中的编号。第一个信号的编号为0;

sem_op

:如果其值为正数,该值会加到现有的信号内含值中。通常用于释放所控资源的使用权;如果sem_op的值为负数,而其绝对值又大于信号的现值,操作将会阻塞,直到信号值大于或等于sem_op的绝对值。通常用于获取资源的使用权;如果sem_op的值为0,则操作将暂时阻塞,直到信号的值变为0。

_semflgIPC_NOWAIT

//对信号的操作不能满足时,semop()不会阻塞,并立即返回,同时设定错误信息。

IPC_UNDO

//程序结束时(不论正常或不正常),保证信号值会被重设为semop()调用前的值。这样做的目的在于避免程序在异常情况下结束时未将锁定的资源解锁,造成该资源永远锁定。

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

union semun

{

int val;

struct semid_ds *buf;

unsigned short *array;

};

union semun sem_union;

struct sembuf sem_buf;

key_t key = 0;

int sem_id = 0;

unsigned short arry[2] = {0,2};

int main()

{

sem_union.array=arry;

key =

ftok("./123",1); //获取键值

//创建信号量

//int semget(key_t _key ,int _nsems,int _semflg);

//key_t sem键值 _nsems 创建信号量个数 _semflg 创建属性

sem_id = semget(key, 2, 0666 | IPC_CREAT);

printf("sem_id =

%d\n",sem_id); //打印semID

if (semctl(sem_id,1,SETALL,sem_union)==-1)

{

perror("Sem init");

exit(1);

}

sem_buf.sem_num=1;

sem_buf.sem_op=-1;

sem_buf.sem_flg=SEM_UNDO;

if (semop(sem_id,&sem_buf,1)==-1)

{

perror("Sem P

operation");

exit(1);

}

printf("step 1\n");

sem_buf.sem_num=1;

sem_buf.sem_op=-1;

sem_buf.sem_flg=SEM_UNDO;

if (semop(sem_id,&sem_buf,1)==-1)

{

perror("Sem P

operation");

exit(1);

}

printf("END\n");

return 0;

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux 中,可以使用 `semctl` 系统调用中的 `GETVAL` 命令来获取指定信号的值。如果该值为0,则表示信号已经被占用,没有可用的资源。 具体的代码实现可以参考如下示例: ```c #include <stdio.h> #include <stdlib.h> #include <sys/sem.h> int main() { int semid; struct sembuf sb; // 创建信号semid = semget(IPC_PRIVATE, 1, 0666 | IPC_CREAT); if (semid == -1) { perror("semget"); exit(EXIT_FAILURE); } // 初始化信号 if (semctl(semid, 0, SETVAL, 1) == -1) { perror("semctl"); exit(EXIT_FAILURE); } // 获取信号的值 printf("Sem value: %d\n", semctl(semid, 0, GETVAL)); // 尝试获取信号 sb.sem_num = 0; sb.sem_op = -1; // P 操作 sb.sem_flg = SEM_UNDO; if (semop(semid, &sb, 1) == -1) { perror("semop"); exit(EXIT_FAILURE); } printf("Semaphore acquired\n"); // 释放信号 sb.sem_op = 1; // V 操作 if (semop(semid, &sb, 1) == -1) { perror("semop"); exit(EXIT_FAILURE); } printf("Semaphore released\n"); // 删除信号集 if (semctl(semid, 0, IPC_RMID, 0) == -1) { perror("semctl"); exit(EXIT_FAILURE); } return 0; } ``` 在这个示例中,我们首先使用 `semget` 系统调用创建了一个信号集,并使用 `semctl` 系统调用对该信号进行了初始化。然后使用 `semctl` 系统调用获取了该信号的值,并输出到控制台。 接下来,我们使用 `semop` 系统调用进行了一次 P 操作,即尝试获取该信号。如果该信号的值为0,则该操作将会被阻塞,直到信号的值变为非0。在本例中,由于我们已经将信号初始化为1,因此该 P 操作可以顺利完成。 最后,我们使用 `semop` 系统调用进行了一次 V 操作,即释放该信号。然后使用 `semctl` 系统调用删除了该信号集。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值