标签:信号量实现进程通信
一.信号量
信号量是一种数据操作锁,本身不具有数据交换功能,而是通过控制其他的通信资源来实现进程之间的通信,简单来讲,信号量相当于一个计数器,计数当前某种资源的个数。信号量的周期也是随内核的。为了解决多个程序同时访问一个共享资源引发的问题。
临界资源:多个进程能访问到的公共资源。
临界区:将能访问带临界资源的代码成为临界区。
同步:对临界资源的访问具有顺序性。
pv 操作
p(sv) sv>0 减1 sv=0 挂起的该进程执行
s(sv) 没有进程因等待sv而挂起就加1,有进程等待sv被挂起,就恢复运行。
信号量用到的函数:
int semget(key_t key,int nsems,int smflag)//nsems:信号量个数
以信号量集为基本单位进行申请。
int semctl(int semid, int semnum, int cmd, ...);//semnum:第几个信号量
信号量实现进程间通信:
//comm.h
1
2 #pragma once
3 #include<unistd.h>
4 #include<stdlib.h>
5 #include<stdio.h>
6 #include<sys/types.h>
7 #include<sys/sem.h>
8 #include<sys/ipc.h>
9 #define _PATH_ "."
10 #define _PROJ_ID_ 0x7777
11
12 union semun
13 {
14 int val;
15 struct semid_ds *buf;
16 unsigned short *array;
17 struct seminfo *_buf;
18 };
19 static int comm(int __sem_nums,int flag);
20 int create_sem_set(int _sem_nums);
21 int get_sem_set(int _sem_nums);
22 int init_sem_set(int _sem_id,int _sem_num,int _sem_val);
23 int p_sem_elem(int _sem_id ,int _sem_num);
24 int v_sem_elem(int _sem_id,int _sem_num);
25 int destroy_sem(int _sem_id);
~
//comm.c
1 #include"comm.h"
2 static int comm(int _sem_nums,int flag)
3 {
4 key_t key=ftok(_PATH_,_PROJ_ID_);
5 if(key<0)
6 {
7 perror("ftok");
8 return -1;
9 }
10 int sem_id=semget(key,_sem_nums,flag);
11 if(sem_id<0)
12 {
13 perror("semget");
14 return -1;
15 }
16
17 return sem_id;
18
19 }
20 int create_sem_set(int _sem_nums)
21 {
22 int flag=IPC_CREAT|IPC_EXCL|0666;
23 return comm(_sem_nums,flag);
24
25
26 }
27 int get_sem_set(int _sem_nums)
28 {
29 int flag=IPC_CREAT;
30 return comm(_sem_nums,flag);
31 }
32 int init_sem_set(int _sem_id,int _sem_num,int _sem_val)
33 {
34 union semun _un;
35 _un.val=_sem_val;
36 if(semctl(_sem_id,_sem_num,SETVAL,_un)<0)
37 {
38 perror("semctl");
39 return -1;
40
41 }
42 return 0;
43 }
44 int p_sem_elem(int _sem_id ,int _sem_num)
45 {
46 struct sembuf _sem_buf[1];
47 _sem_buf[0].sem_num=_sem_num;
48 _sem_buf[0].sem_op=-1;
49 _sem_buf[0].sem_flg=0;
50 if(semop(_sem_id,_sem_buf,1)<0)
51 {
52 perror("semop");
53 return -1;
54
55 }
56 return 0;
57 }
58 int v_sem_elem(int _sem_id,int _sem_num)
59 {
60 struct sembuf _sem_buf[1];
61 _sem_buf[0].sem_num=_sem_num;
62 _sem_buf[0].sem_op=1;
63 _sem_buf[0].sem_flg=0;
64 if(semop(_sem_id,_sem_buf,1)<0)
65 {
66 perror("semop");
67 return -1;
68
69 }
70 return 0;
71
}
74 int destroy_sem(int _sem_id)
75 {
76 if(semctl(_sem_id,0,IPC_RMID,NULL)<0)
77 {
78 perror("semctl");
79 return -1;
80
81
82 }
83 return 0;
}
91 int main()
92 {
93 int sem_id=create_sem_set(1);
94 init_sem_set(sem_id,0,1);
95 pid_t pid=fork();
96 if(pid<0)
97 {
98 perror("fork");
99 exit(1);
100 }
101
102 else if(pid==0)
103 {
104 int sem_id=get_sem_set(1);
105 while(1)
106 {
107 p_sem_elem(sem_id,0);
108 printf("A");
109 sleep(1);
110 fflush(stdout);
111 printf("A");
112 sleep(7);
113 fflush(stdout);
114 v_sem_elem(sem_id,0); 116 }
117 }
118
119 else
120 {
121 while(1)
122 {
123 p_sem_elem(sem_id,0);
124
125 printf("B");
126 sleep(2);
127 fflush(stdout);
128 printf("B");
129 sleep(5);
130 fflush(stdout);
131 v_sem_elem(sem_id,0);
132
133
134 }
135 } return 0;
}程序运行结果:
本文出自 “输出菱形图案” 博客,请务必保留此出处http://10541571.blog.51cto.com/10531571/1764306
标签:信号量实现进程通信
原文地址:http://10541571.blog.51cto.com/10531571/1764306