信号量---解决进程间的同步与互斥问题之1
2013-07-25 16:27
465 查看
信号量(初步了解)
信号量:主要用于解决同步于互斥的问题
主要的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
信号量:主要用于解决同步于互斥的问题
主要的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
相关文章推荐
- 用信号量解决进程的同步与互斥
- 用信号量做进程同步解决生产者和消费者遇到的奇怪问题
- 单车道问题 - 进程同步互斥与死锁问题的解决
- 用信号量解决进程的同步与互斥探讨【持续更新】
- linux网络编程之System V 信号量(二):用信号量实现进程互斥示例和解决哲学家就餐问题
- linux网络编程之System V 信号量(二):用信号量实现进程互斥示例和解决哲学家就餐问题
- 用信号量解决进程的同步与互斥探讨
- Linux下信号量实现进程同步、互斥(生产者消费者问题)
- 运用信号量解决进程同步问题之整型信号机制、记录型信号量机制、信号量集机制
- 信号量解决进程的同步和互斥
- 用PV操作解决进程之间的同步互斥问题
- 用信号量实现进程互斥示例和解决哲学家就餐问题
- 操作系统之信号量解决同步互斥问题
- 在iOS中有几种方法来解决多线程访问同一个内存地址的互斥同步问题
- 进程(线程)间同步互斥问题(四) 三个烟鬼问题
- 进程同步---生产者与消费者问题以及进程同步机制--信号量及P、V操作
- 【操作系统】进程(线程)间同步互斥问题——熟睡的理发师问题
- 进程同步与互斥:POSIX有名信号量
- Operating System-进程/线程内部通信-信号量、PV操作的实现和应用(解决哲学家进餐和生产者消费者问题)
- 进程同步与互斥之经典问题二