linux c 进程信号量,LinuxC进程通信-信号量

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

006tNc79gy1fsef9zuudkj30hs0budh6.jpg

信号量的创建或者打开1int semget(key_t key,int nsems,int semflg);参数说明:

返回值:若成功,返回一个信号集的标识符,失败返回-1

key:第一个参数由ftok()函数得到的键值

nsems:第二个参数指明要创建的信号集包含的信号个数,如果只是打开信号集,把nsems设置为0即可

semflg:第三个参数为操作标志

IPC_CREATE:调用semget()时,他会将此值与系统中其他信号集的key进行比较奥,如果存在相同的key,

说明信号集已存在,此时返回该信号集的标识符,否则新建一个信号集并返回其标识符。

IPC_EXCL:该宏须和IPC_CREATE一起使用,否则没有意义。当semflg取IPC_CREATE|IPC_EXCL时,

表示如果发现该信号集已经存在,则返回错误,错误吗为EEXIST

创建信号量并对信号集中所有信号进行初始化的函数1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27int createsem(const char *pathname,int proj_id,int members,int init_val)

{

key_t msgkey;

int index,sid;

union semun semopts;

// 获取键值

if((msgkey = ftok(pathname,proj_id)) == -1)

{

perror("semget call failed.n");

return -1;

}

if((sid = semget(msgkey,members,IPC_CREATE|0666)) == -1)

{

perror("semget call failed.n");

return -1;

}

// 初始化操作

semopts.val = init_val;

for(index = 0;index < members;index++)

{

semctl(sid,index,SETVAL,semopts);

}

return (sid);

}

信号量的操作信号量的值与相应资源的使用情况有关,当它的值大于0时,表示当前可用资源的数量,当它的值小于0时,其绝对值表示等待使用该资源的进程个数。信号量的值仅能由PV操作来改变。1int semop(int semid,struct sembuf *sops,size_t nsops);参数说明:

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

semid:semid为信号集的标识符

sops:指向进行操作的结构体数组首地址

nsops: 指出将要进行操作的信号的个数

semop的第二个参数sops指向的结构体数组中,每个sembuf结构体对应一个特定信号的操作

因此对信号进行操作必须熟悉该数据结构1

2

3

4

5struct sembuf{

ushort sem_num; /* 信号在信号集中的索引 */

short sem_op; /* 操作类型 见下表*/

short sem_flg; /* 操作标志 */

}取值范围操作意义sem_op > 0信号加上sem_op的值,表示进程释放控制的资源

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

sem_op < 0信号加上sem_op的值。如果没有设置IPC_NOWAIT,则调用进程阻塞,z直到资源可用。否则进程直接返回EAGAIN

对一个信号集中的某个信号进行操作的P,V函数1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19/* P操作函数 */

int sem_p(int semid,int index)

{

struct sembuf buf = {0,-1,IPC_NOWAIT};

if(index < 0)

{

perror("index of array cannot equals a minux value!");

return -1;

}

buf.sem_num = index;

if(semop(semid,&buf,1) == -1)

{

perror("a wrong operation to semaphore occurred!");

return -1;

}

return 0;

}

信号集的控制

使用信号量时,往往需要对信号集进行一些控制操作,比如删除信号集,对内核维护的信号集的数据结构semid_ds进行设置,获取信号集中信号值等。1int semctl(int semid,int semnum,int cmd,...);参数说明:

semid:信号集的标识符

semnum:标识一个特定的信号

cmd:指明控制操作的类型

最后的”…”说明函数的参数是可选的,他依赖于第三个参数cmd,他通过共用体变量semun选择要操作的参数

semun定义在include/sem.h1

2

3

4

5

6

7union semun{

int val;

struct semid_ds *buf;

ushort *array;

struct seminfo *buf;

void *pad;

};

各字段的含义如下:val:仅用于SETVAL操作类型,设置某个信号的值等于val

buf: 用于IPC_STAT和IPC_SET操作,存取semid_ds结构

array:用于SETALL和GETALL操作

buf:为控制IPC_INFO提供的缓存

实例server创建一个信号集,并对信号量循环减1,相当于分配资源。client执行时检查信号量,如果其值大于0代表有资源可用,继续执行,如果小于0代表资源已经分配完毕,进程client退出。1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107/*************************************************************************

> File Name: server.c

> Author: xiaorui

> Created Time: 2017年11月26日 星期日 15时22分23秒

> Function: server创建一个信号集,并对信号量循环减1,相当于分配资源。

client执行时检查信号量,如果其值大于0代表有资源可用,继续执行,

如果小于0代表资源已经分配完毕,进程client退出。

************************************************************************/

#include

#include

#include

#include

#include

#define MAX_RESOURCE 5

int main(void)

{

key_t key;

int semid;

struct sembuf sbuf = {0,-1,IPC_NOWAIT};

union semun semopts;

if((key = ftok(".",'s')) == -1)

{

perror("ftok error!n");

exit(1);

}

if((semid = semget(key,1,IPC_CREAT|0666)) == -1)

{

perror("semget error!n");

exit(1);

}

semopts.val = MAX_RESOURCE;

if(semctl(semid,0,SETVAL,semopts) == -1)

{

perror("semctl error!n");

exit(1);

}

while(1)

{

if(semop(semid,&sbuf,1) == -1)

{

perror("semop error!n");

exit(1);

}

sleep(3);

}

exit(0);

}

/*************************************************************************

> File Name: client.c

> Author: xiaorui

> Created Time: 2017年11月26日 星期日 15时45分53秒

************************************************************************/

#include

#include

#include

#include

int main(void)

{

key_t key;

int semid,semval;

union semun semopts;

if((key = ftok(".",'s')) == -1)

{

perror("ftok error!n");

exit(1);

}

if((semid = semget(key,1,IPC_CREAT|0666)) == -1)

{

perror("semget error!n");

exit(1);

}

while(1)

{

if((semval = semctl(semid,0,GETVAL,0)) == -1)

{

perror("semctl error!n");

exit(1);

}

if(semval > 0)

{

printf("Still %d resources can be usedn",semval);

}

else

{

printf("No more resources can be used!n");

break;

}

sleep(3);

}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值