信号量(初步了解)
信号量:主要用于解决同步于互斥的问题
主要的api:
Int semget(key_t,key,int nsems,int semflg); 主要用于创建信号,第一个参数:和信号灯(该值是一个你要用到的信号)关联的值;第二个参数:要创建信号的数目;第三个参数:访问权限,一般是:IPC_CREAT | 0666 ;该函数的返回值是一个信号灯集的id
Int semctl(int semid,int semnum,int cmd ...); 该函数主要用于控制信号,如果,该函数中的信号没有使用,那么返回0,如果在使用返回1;第一个参数:信号灯集的id;第二个参数:要用到的信号灯的编号(从0开始编号的);第三个参数:GETVAL:用来获取信号灯的值(具体其他值,可以查man手册)
Int semop(int semid ,struct sembuf *opsptr,seze_t nops) ; 该函数主要是用于向一个信号发送去一个消息(用于释放资源,或者分配资源======这里描述可能不准确) ;第一个参数:需要发送信息的信号,第三个参数:要操作的信号灯的个数:
第二个参数:是一个结构体 具体成员可以查满手册:第一成员是:sem_num;要操作的灯的编号(从0开始编号的);第二个参数:sem_op(0--表示等待,知道信号灯变为0位置;1---表示释放资源,v操作(我在线程中有简要描述这个概念);-1 ----表示分配资源,p操作)
下面是一个关于进程间通信,用共享内存实现,同步机制用信号量来实现的一段小代码(参考):下面的两个进程必须在相同的目录下,当然也可以不适用ftok函数,来实现在不同的目录下:
读进程:
1 #include<sys/ipc.h>
2 #include<sys/shm.h>
3 #include<stdio.h>
4 #include<stdlib.h>
5 #include<errno.h>
6 #include<sys/types.h>
7 #include<sys/sem.h>
8 #include<unistd.h>
9
10 #define MAX_SIZE 1024
11 int main(int argc,char *argv[]) {
12 key_t key;
13 int pid;
14 char *buf;
15 struct sembuf sem_buf;
16 if((key = ftok(".",'a')) < 0) {
17 perror("get key error \n");
18 exit(-1);
19 }
20
21 if ( (pid = shmget(key,MAX_SIZE,0666 | IPC_CREAT)) < -1) {
22 if(errno == EEXIST) {
23 // perror("exit memory\n");
24 ;
25 } else {
26 perror("creat share memory\n");
27 exit(-1);
28 }//if
29 }//if
30
31 int read_id,write_id;
32 if ( (read_id = semget(1000,1,IPC_CREAT | 0666)) < 0 ) {
33 perror("creat read id error\n");
34 exit(-1);
35 }
36
37 if( (write_id = semget(1005,1,IPC_CREAT | 0666)) < 0) {
38 perror("creat write id error\n");
39 exit(-1);
40 }
41
42 if ( (buf = (char *)shmat(pid,NULL,0)) == (char *)-1) {
43 perror("shmat error\n");
44 exit(-1);
45 }
46
47 if ( semctl(read_id,0,GETVAL)== 0 && semctl(write_id,0,GETVAL)== 0 ) {
48 sem_buf.sem_num = 0;
49 sem_buf.sem_op = 1;
50
51 if( semop(write_id,&sem_buf,1) < 0) {
52 perror("semop write_id error\n");
53 exit(-1);
54 }
55 }
56
57 while(1) {
58 printf("in while\n");
59 sem_buf.sem_num =0 ;
60 sem_buf.sem_op = -1;
61 sem_buf.sem_flg =0;
62 if( semop(read_id,&sem_buf,1) < 0 ) {
63 perror("read_id error\n");
64 exit(-1);
65 }
66
67 sleep(3);
68 write(STDOUT_FILENO,buf,1);
69 sem_buf.sem_num=0;
70 sem_buf.sem_op =1;
71 semop(write_id,&sem_buf,1);
72
73 }//while
74
75 }//main
76
77
下面是写进程:
1 #include<sys/ipc.h>
2 #include<sys/shm.h>
3 #include<stdio.h>
4 #include<stdlib.h>
5 #include<errno.h>
6 #include<sys/types.h>
7 #include<sys/sem.h>
8 #include<unistd.h>
9
10 #define MAX_SIZE 1024
11 int main(int argc,char *argv[]) {
12 key_t key;
13 int pid;
14 char *buf;
15 struct sembuf sem_buf;
16 if((key = ftok(".",'a')) < 0) {
17 perror("get key error \n");
18 exit(-1);
19 }
20
21 if ( (pid = shmget(key,MAX_SIZE,0666 | IPC_CREAT)) < -1) {
22 if(errno == EEXIST) {
23 // perror("exit memory\n");
24 ;
25 } else {
26 perror("creat share memory\n");
27 exit(-1);
28 }//if
29 }//if
30
31 int read_id,write_id;
32 if ( (read_id = semget(1000,1,IPC_CREAT | 0666)) < 0 ) {
33 perror("creat read id error\n");
34 exit(-1);
35 }
36
37 if( (write_id = semget(1005,1,IPC_CREAT | 0666)) < 0) {
38 perror("creat write id error\n");
39 exit(-1);
40 }
41
42 if ( (buf = (char *)shmat(pid,NULL,0)) == (char *)-1) {
43 perror("shmat error\n");
44 exit(-1);
45 }
46
47 if ( semctl(read_id,0,GETVAL)== 0 && semctl(write_id,0,GETVAL)== 0 ) {
48 sem_buf.sem_num = 0;
49 sem_buf.sem_op = 1;
50
51 if( semop(read_id,&sem_buf,1) < 0) {
52 perror("semop read_id error\n");
53 exit(-1);
54 }
55 }
56
57 buf[0]= 'a' -1;
58
59 while(1) {
60
61 sem_buf.sem_num =0 ;
62 sem_buf.sem_op = -1;
63 sem_buf.sem_flg =0;
64 if( semop(write_id,&sem_buf,1) < 0 ) {
65 perror("read_id error\n");
66 exit(-1);
67 }
68
69 // sleep(3);
70 // write(STDOUT_FILENO,buf,1);
71 buf[0] = buf[0] + 1;
72 sem_buf.sem_num=0;
73 sem_buf.sem_op =1;
74 semop(read_id,&sem_buf,1);
75
76 }//while
77
78 }//main
79
80