sem_wait的函数说明

sem_wait的函数说明,第1张

sem_wait函数也是一个原子操作,它的作用是从信号量的值减去一个“1”,但它永远会先等待该信号量为一个非零值才开始做减法。也就是说,如果你对一个值为2的信号量调用sem_wait(),线程将会继续执行,将信号量的值将减到1。如果对一个值为0的信号量调用sem_wait(),这个函数就会原地等待直到有其它线程增加了这个值使它不再是0为止。如果有两个线程都在sem_wait()中等待同一个信号量变成非零值,那么当它被第三个线程增加 一个“1”时,等待线程中只有一个能够对信号量做减法并继续执行,另一个还将处于等待状态。sem_trywait(sem_t *sem)是函数sem_wait的非阻塞版,它直接将信号量sem减1,同时返回错误代码。

sem_wait() 减小(锁定)由sem指定的信号量的值.如果信号量的值比0大,那么进行减一的操作,函数立即返回.如果信号量当前为0值,那么调用就会一直阻塞直到或者是信号量变得可以进行减一的操作(例如,信号量的值比0大),或者是信号处理程序中断调用

sem_trywait() 和 sem_wait()是一样的,除了如果不能够对信号量立即进行减一,那么sem_trywait()就会返回一个错误(错误号是AGAIN)而不是锁定.sem_timedwait() 和 sem_wait()是一样的,除了如果减一操作不能立即执行的话,abs_timeout 指定了调用应该被阻塞的时间限制.abs_timeout 参数指向了一个结构体指定了由秒和纳秒组成的绝对的超时值:从1970-01-01 00:00:00 +0000纪元开始的UTC,结构体的定义如下:struct timespec {time_t tv_sec/* Seconds */long tv_nsec/* Nanoseconds [0 .. 999999999] */}如果超时值已经超过了调用规定的值,那么信号量不能被立即锁定,之后sem_timedwait() 为超时失败(error设置为ETIMEDOUT).

如果操作立即生效,那么sem_timedwait() 永远不会返回超时的错误,不管abs_timeout的值.更进一步的是,在这种情况下abs_timeout值的有效性都不会检查. EINTR The call was interrupted by a signal handlersee signal(7).//调用被信号处理中断

EINVAL sem is not a valid semaphore.//sem不是有效的信号量

The following additional error can occur for sem_trywait()://下面的错误是sem_trywait()可能发生的:

EAGAIN The operation could not be performed without blocking (i.e., thesemaphore currently has the value zero).//除了锁定无法进行别的操作(如信号量当前是0值).

The following additional errors can occur for sem_timedwait()://下面的错误是sem_timedwait()可能发生的:

EINVAL The value of abs_timeout.tv_nsecs is less than 0, or greater than orequal to 1000 million.//abs_timeout.tv_nsecs 的值比0小或者大于等于1000毫秒(译者注:纳秒的值不能比0小,不能比1秒大)

ETIMEDOUTThe call timed out before the semaphore could be locked.//在信号量锁定之前就超时了 对这些函数,信号处理程序总是会中断阻塞,不管是否使用了sigaction(2)的SA_RESTART标志位.

/*编译命令:gcc -o shm shm.c -g */

2

3#include<sys/sem.h>

4#include<sys/ipc.h>

5

6#define SEGSIZE 1024

7#define READTIME 1

8

9union semum

10{

11int val

12struct semid_ds *buf

13unsigned short *array

14}arg

15

16/* 创建信号量 */

17int sem_creat(key_t key)

18{

19union semun sem

20int semid

21sem.val = 0

22semid = semget(key, 1, IPC_CREAT | 0666)

23

24if (semid == -1)

25{

26printf("Create semaphore error\n")

27exit(-1)

28}

29

30semctl(semid, 0, SETVAL, sem)

31

32return semid

33}

34

35/* 删除信号量*/

36int del_sem(int semid)

37{

38union semun sem

39sem.val = 0

40semctl(semid, 0, IPC_RMID, sem)

41}

42

43/* 信号量的P操作,使得信号量的值加1 */

44int p(int semid)

45{

46struct sembuf sops = {0,

47 +1,

48 IPC_NOWAIT

49 }

50

51return (semop(semid, &sops, 1))

52}

53

54/* 信号量的v操作,使得信号量的值减1 */

55int v(int semid)

56{

57struct sembuf sops = {0,

58 -1,

59 IPC_NOWAIT

60 }

61

62return (semop(semid, &sops, 1))

63}

64

65/* server主程序 */

66int main(int argc, char **argv)

67{

68key_tkey

69int shmid, semid

70char *shm

71char msg[7] = "-data-"

72char i

73struct semid_ds buf

74

75key = ftok("/", 0)

76shmid = shmget(key, SEGSIZE, IPC_CREAT|0604)

77

78if shmid == -1)

79{

80printf(" create shared memory error\n")

81return -1

82}

83

84shm = (char *)shmat(shmid, 0, 0)

85if (-1 == (int)shm)

86{

87printf(" attach shared memory error\n")

88return -1

89}

90

91semid = sem_creat(key)

92

93for (i = 0i <= 3i++)

94{

95sleep(1)

96p(semid)

97sleep(READTIME)

98msg[5] = '0' + i

99memcpy(shm,msg,sizeof(msg))

100sleep(58)

101v(semid)

102}

103

104shmdt(shm)

105

106shmctl(shmid,IPC_RMID,&buf)

107

108del_sem(semid)

109

110return 0

111

112}

113

114

115

116

117

118

119

120

121


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/217035.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-06
下一篇2023-04-06

发表评论

登录后才能评论

评论列表(0条)

    保存