信号量---解决进程间的同步与互斥问题之1

信号量(初步了解)

信号量:主要用于解决同步于互斥的问题

主要的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_op0--表示等待,知道信号灯变为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 

                                                   

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值