linux pv 信号量,Linux信号量PV操作

1://假设两个进程(父子进程)对一个文件进行写操作,但是这个文件同一时间只能有一个进程进行写操作。

2://利用信号量实现pv操作

3:#include

4:#include

5:#include

6:#include

7:#include

8:#include

9:struct sembuf sops;

10:static int sid;

11://创建一个新的信号量集

12:int createSemset(void)

13:{

14:char* pathname="semset";

15:if( access(pathname, F_OK)!=0 )

16:{

17:int fd=open(pathname, O_RDWR | O_CREAT, 0666);

18:if( fd<0 )

19:{

20:perror("open");

21:return -1;

22:}

23:}

24:key_t key=ftok(pathname, 'a');

25:if( -1==key )

26:{

27:perror("ftok");

28:return -1;

29:}

30:return semget(key, 1, IPC_CREAT | 0666) ;

31:}

32:

33://P操作

34:int P(void)

35:{

36:sops.sem_num=0;

37:sops.sem_op=-1;

38:sops.sem_flg=0;

39:return semop(sid, &sops, 1);

40:}

41://V操作

42:int V(void)

43:{

44:sops.sem_num=0;

45:sops.sem_op=1;

46:sops.sem_flg=0;

47:return semop(sid, &sops, 1);

48:}

49:int main(int argc, char *argv[])

50:{

51:sid=createSemset();

52:if( -1==sid )

53:{

54:perror("createSemset");

55:exit(1);

56:}

57:

58:if( -1==semctl(sid, 0, SETVAL, 1) )

59:{

60:perror("SETVAL");

61:exit(1);

62:}

63:pid_t pid=fork();

64:if( pid<0 )

65:{

66:perror("fork");

67:exit(1);

68:}

69:else if( 0==pid )

70:{

71:while(1)

72:{

73:if( -1==P() )

74:{

75:printf("P操作失败!

");

76:exit(1);

77:}

78:printf("子进程正在对文件进行写操作!

");

79:sleep(1);

80:printf("子进程写操作完毕,释放资源!

");

81:if( -1==V() )

82:{

83:printf("V操作失败!");

84:exit(1);

85:}

86:}

87:}

88:else

89:{

90:while(1)

91:{

92:if( -1==P() )

93:{

94:printf("P操作失败!

");

95:exit(1);

96:}

97:printf("父进程进程正在对文件进行写操作!

");

98:sleep(1);

99:printf("父进程写操作完毕,释放资源!

");

100:if( -1==V() )

101:{

102:printf("V操作失败!");

103:exit(1);

104:} ......

1:void P(int semid)

2:{

3: struct sembuf sem_p;

4: sem_p.sem_num = 0;

5: sem_p.sem_op = -1;

6: sem_p.sem_flg = SEM_UNDO;

7: if (semop(semid, &sem_p, 1) == -1) {

8: perror("p op failed

");

9: exit(1);

10: }

11:}

12:

13:void V(int semid)

14:{

15: struct sembuf sem_p;

16: sem_p.sem_num = 0;

17: sem_p.sem_op = 1;

18: sem_p.sem_flg = SEM_UNDO;

19: if (semop(semid, &sem_p, 1) == -1) {

20: perror("v op failed

");

21: exit(1);

22: }

23:}

PV原语通过操作信号量来处理进程间的同步与互斥的问题。其核心就是一段不可分割不可中断的程序。

信号量的概念1965年由著名的荷兰计算机科学家Dijkstra提出,其基本思路是用一种新的变量类型(semaphore)来记录当前可用资源的数量。有两种实现方式:1)semaphore的取值必须大于或等于0。0表示当前已没有空闲资源,而正数表示当前空闲资源的数量;2) semaphore的取值可正可负,负数的绝对值表示正在等待进入临界区的进程个数。

信号量是由操作系统来维护的,用户进程只能通过初始化和两个标准原语(P、V原语)来访问。初始化可指定一个非负整数,即空闲资源总数。

P原语:P是荷兰语Proberen(测试)的首字母。为阻塞原语,负责把当前进程由运行状态转换为阻塞状态,直到另外一个进程唤醒它。操作为:申请一个空闲资源(把信号量减1),若成功,则退出;若失败,则该进程被阻塞;

V原语:V是荷兰语Verhogen(增加)的首字母。为唤醒原语,负责把一个被阻塞的进程唤醒,它有一个参数表,存放着等待被唤醒的进程信息。操作为:释放一个被占用的资源(把信号量加1),如果发现有被阻塞的进程,则选择一个唤醒之。

具体PV原语对信号量的操作可以分为三种情况:

1)把信号量视为一个加锁标志位,实现对一个共享变量的互斥访问。

实现过程:

P(mutex); // mutex的初始值为1 访问该共享数据;

V(mutex);

非临界区

2)把信号量视为是某种类型的共享资源的剩余个数,实现对一类共享资源的访问。

实现过程:

P(resource); // resource的初始值为该资源的个数N 使用该资源;

V(resource); 非临界区

3)把信号量作为进程间的同步工具

实现过程:

临界区C1;

P(S);

V(S);

临界区C2;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值