信号量介绍 (转)

本文深入讲解了信号量机制的基本概念,包括信号量的作用原理、组成元素及其操作方式,并提供了信号量创建、控制及操作的具体函数介绍。此外,还通过一个完整的服务器与客户端实例展示了信号量在实际应用中的实现细节。
摘要由CSDN通过智能技术生成

一、相关知识  信号量:一个整数;   大于或等于0时代表可供并发进程使用的资源实体数;   小于0时代表正在等待使用临界区的进程数;   用于互斥的信号量初始值应大于0;   只能通过P、V原语操作而改变;  信号量元素组成:   1、表示信号量元素的值;   2、最后操作信号量元素的进程ID   3、等待信号量元素值+1的进程数;   4、等待信号量元素值为0的进程数;   二、主要函数    1.1 创建信号量  int semget(   key_t key,  //标识信号量的关键字,有三种方法:1、使用IPC——PRIVATE让系统产生,      // 2、挑选一个随机数,3、使用ftok从文件路径名中产生   int nSemes,  //信号量集中元素个数   int flag  //IPC_CREAT;IPC_EXCL 只有在信号量集不存在时创建  )  成功:返回信号量句柄  失败:返回-1    1.2 使用ftok函数根据文件路径名产生一个关键字  key_t ftok(const char *pathname,int proj_id);  路径名称必须有相应权限     1.3 控制信号量  int semctl(   int semid,  //信号量集的句柄   int semnum,  //信号量集的元素数   int cmd,  //命令   /*union senum arg */... //    )  成功:返回相应的值  失败:返回-1    命令详细说明:  cmd:   IPC_RMID 删除一个信号量   IPC_EXCL 只有在信号量集不存在时创建   IPC_SET 设置信号量的许可权   SETVAL 设置指定信号量的元素的值为 agc.val   GETVAL 获得一个指定信号量的值   GETPID 获得最后操纵此元素的最后进程ID   GETNCNT 获得等待元素变为1的进程数   GETZCNT 获得等待元素变为0的进程数     union senum 定义如下:  union senum{   int val;   struct semid_ds *buf;   unsigned short * array;  }agc;  其中 semid_ds 定义如下:  struct semid_ds{   struct ipc_pem sem_pem;  //operation pemission struct   time_t sem_otime;  //last semop()time   time_t sem_ctime;  //last time changed by semctl()   struct sem *sembase;  //ptr to first semaphore in array   struct sem_queue *sem_pending; //pending operations   struct sem_queue *sem_pending_last; //last pending operations   struct sem_undo *undo;  //undo requests on this arrary   unsigned short int sem_nsems; //number of semaphores in set  };     1.4 对信号量 +1 或 -1 或测试是否为0  int semop(   int semid,    struct sembuf *sops, //指向元素操作数组   unsigned short nsops //数组中元素操作的个数  )    结构 sembuf 定义  sembuf{   short int sem_num; //semaphore number   short int sem_op; //semaphore operaion   short int sem_flg //operation flag  };   三、例子:  2.1 服务器

#include <sys/sem.h> #include <sys/ipc.h> #define SEGSIZE 1024 #define READTIME 1 union semun {  int val;  struct semid_ds *buf;  unsigned short *array; } arg; //生成信号量 int sem_creat(key_t key) {  union semun sem;  int semid;  sem.val = 0;  semid = semget(key,1,IPC_CREAT|0666);  if (-1 == semid){   printf("create semaphore error/n");   exit(-1);  }  semctl(semid,0,SETVAL,sem);  return semid; } //删除信号量 void del_sem(int semid) {  union semun sem;  sem.val = 0;  semctl(semid,0,IPC_RMID,sem); } //p int p(int semid) {  struct sembuf sops={0,+1,IPC_NOWAIT};  return (semop(semid,&sops,1)); } //v int v(int semid) {  struct sembuf sops={0,-1,IPC_NOWAIT};  return (semop(semid,&sops,1)); } int main() {  key_t key;  int shmid,semid;  char *shm;  char msg[7] = "-data-";  char i;  struct semid_ds buf;    key = ftok("/",0);  shmid = shmget(key,SEGSIZE,IPC_CREAT|0604);  if (-1 == shmid){   printf(" create shared memory error/n");   return -1;  }  shm = (char *)shmat(shmid,0,0);  if (-1 == (int)shm){   printf(" attach shared memory error/n");   return -1;  }  semid = sem_creat(key);  for (i = 0;i <= 3;i++){   sleep(1);   p(semid);   sleep(READTIME);   msg[5] = '0' + i;   memcpy(shm,msg,sizeof(msg));   sleep(58);   v(semid);  }  shmdt(shm);  shmctl(shmid,IPC_RMID,&buf);  del_sem(semid);  return 0; //gcc -o shm shm.c -g }

   2.2 客户端  

#include <sys/sem.h> #include <time.h> #include <sys/ipc.h> #define SEGSIZE 1024 #define READTIME 1 union semun {  int val;  struct semid_ds *buf;  unsigned short *array; } arg; // 打印程序执行时间 void out_time(void) {  static long start = 0;  time_t tm;  if (0 == start){   tm = time(NULL);   start = (long)tm;   printf(" now start .../n");  }  printf(" second: %ld /n",(long)(time(NULL)) - start); } //创建信号量 int new_sem(key_t key) {  union semun sem;  int semid;  sem.val = 0;  semid = semget(key,0,0);  if (-1 == semid){   printf("create semaphore error/n");   exit(-1);  }  return semid; } //等待信号量变成0 void wait_v(int semid) {  struct sembuf sops={0,0,0};  semop(semid,&sops,1); } int main(void) {  key_t key;  int shmid,semid;  char *shm;  char msg[100];  char i;    key = ftok("/",0);  shmid = shmget(key,SEGSIZE,0);    if(-1 == shmid){   printf(" create shared memory error/n");   return -1;  }  shm = (char *)shmat(shmid,0,0);  if (-1 == (int)shm){   printf(" attach shared memory error/n");   return -1;  }  semid = new_sem(key);  for (i = 0;i < 3;i ++){   sleep(2);   wait_v(semid);   printf("Message geted is: %s /n",shm + 1);   out_time();  }  shmdt(shm);  return 0; // gcc -o shmc shmC.c -g }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值