微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 进程间通信之: 信号量

进程间通信之: 信号量

时间:08-13 来源:3721RD 点击:

也是第一个信号量)

cmd:指定对信号量的各种操作,当使用单个信号量(而不是信号量集)时,常用的有以下几种:

IPC_STAT:获得该信号量(或者信号量集合)的semid_ds结构,并存放在由第4个参数arg的buf指向的semid_ds结构中。semid_ds是在系统中描述信号量的数据结构。

IPC_SETVAL:将信号量值设置为arg的val值

IPC_GETVAL:返回信号量的当前值

IPC_RMID:从系统中,删除信号量(或者信号量集)

arg:是union semnn结构,该结构可能在某些系统中并不给出定义,此时必须由程序员自己定义

union semun

{

int val;

struct semid_ds *buf;

unsigned short *array;

}

函数返回值

成功:根据cmd值的不同而返回不同的值

IPC_STAT、IPC_SETVAL、IPC_RMID:返回0

IPC_GETVAL:返回信号量的当前值

出错:-1

表8.19列举了semop()函数的语法要点。

表8.19 semop()函数语法要点

所需头文件

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>

函数原型

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

函数传入值

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

sops:指向信号量操作数组,一个数组包括以下成员:

struct sembuf

{

short sem_num; /* 信号量编号,使用单个信号量时,通常取值为0 */

short sem_op;

/* 信号量操作:取值为-1则表示P操作,取值为+1则表示V操作*/

short sem_flg;

/* 通常设置为SEM_UNDO。这样在进程没释放信号量而退出时,系统自动

释放该进程中未释放的信号量 */

}

nsops:操作数组sops中的操作个数(元素数目),通常取值为1(一个操作)

函数返回值

成功:信号量标识符,在信号量的其他函数中都会使用该值

出错:-1

3.使用实例

本实例说明信号量的概念以及基本用法。在实例程序中,首先创建一个子进程,接下来使用信号量来控制两个进程(父子进程)之间的执行顺序。

因为信号量相关的函数调用接口比较复杂,我们可以将它们封装成二维单个信号量的几个基本函数。它们分别为信号量初始化函数(或者信号量赋值函数)init_sem()、P操作函数sem_p()、V操作函数sem_v()以及删除信号量的函数del_sem()等,具体实现如下所示:

/* sem_com.c */

#include "sem_com.h"

/* 信号量初始化(赋值)函数*/

int init_sem(int sem_id, int init_value)

{

union semun sem_union;

sem_union.val = init_value; /* init_value为初始值 */

if (semctl(sem_id, 0, SETVAL, sem_union) == -1)

{

perror("Initialize semaphore");

return -1;

}

return 0;

}

/* 从系统中删除信号量的函数 */

int del_sem(int sem_id)

{

union semun sem_union;

if (semctl(sem_id, 0, IPC_RMID, sem_union) == -1)

{

perror("Delete semaphore");

return -1;

}

}

/* P操作函数 */

int sem_p(int sem_id)

{

struct sembuf sem_b;

sem_b.sem_num = 0; /* 单个信号量的编号应该为0 */

sem_b.sem_op = -1; /* 表示P操作 */

sem_b.sem_flg = SEM_UNDO; /* 系统自动释放将会在系统中残留的信号量*/

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

{

perror("P operation");

return -1;

}

return 0;

}

/* V操作函数*/

int sem_v(int sem_id)

{

struct sembuf sem_b;

sem_b.sem_num = 0; /* 单个信号量的编号应该为0 */

sem_b.sem_op = 1; /* 表示V操作 */

sem_b.sem_flg = SEM_UNDO; /* 系统自动释放将会在系统中残留的信号量*/

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

{

perror("V operation");

return -1;

}

return 0;

}

现在我们调用这些简单易用的接口,可以轻松解决控制两个进程之间的执行顺序的同步问题。实现代码如下所示:

/* fork.c */

#include <sys/types.h> #inclu

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top