笔记七:进程间的通信(IPC通信之信号灯)

信号量
定义信号变量;  sem_t sem1 sem2
初始化信号量
P操作
          V操作  
 功能
信号量(POSOX)
信号量灯(IPC)
定义信号变量
sem_t  sem1
semget
初始化信号量
sem_init
semctl
P操作
sem_wait
semop
V操作
sem_post
semop
 多 线程中的信号量例子:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
#include <string.h>
#include <semaphore.h>

#define N 64

sem_t sem;

void * f(void *arg)
{
      while (1)
      {
            sem_wait(&sem);
            sleep(1);
            printf("%s", (char *)arg);
      }
}

int main()
{
      pthread_t thread;
      char buf[N];      //= "you are welcome";
      void *thread_result;
      
      if (sem_init(&sem, 0, 0) == -1)
      {
            perror("sem_init");
            exit(-1);
      }

      if (pthread_create(&thread, NULL, f, buf) != 0)
      {
            fprintf(stderr, "pthread_create %s\n", strerror(errno));
            exit(-1);
      }

      do
      {
            printf("input:");
            fflush(stdout);
            fgets(buf, N, stdin);
            sem_post(&sem);//唤醒子线程    V操作
      } while (strncmp(buf, "quit", 4));


      return 0;
}
信号灯:
信号灯集合(可以包含多个信号量)  IPC对象是一个 信号灯集 (含有多个信号量)
所有的函数是对一个集合的操作:
int semget(key_t key, int nsems, int semflg);
所需头文件
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
函数原型
int semget(key_t key, int nsems, int semflg);
函数参数
key :和信号灯集关联的 key 
 
nsems:  信号灯集中包含的信号灯数目
 
semflg :信号灯集的访问权限
函数返回值
成功:信号灯集 ID
 
出错: -1
  
所需头文件
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
函数原型
int semop ( int semid, struct sembuf  *opsptr,  size_t  nops);
函数参数
semid :信号灯集 ID

struct sembuf {
   short  sem_num;  // 要操作的信号灯的编号
   short  sem_op;   //  0 :  等待,直到信号灯的值变成 0
                    // 1 :  释放资源, V 操作
                    //   -1 :  分配资源, P 操作                    
   short  sem_flg;     // 0,  IPC_NOWAIT,  SEM_UNDO
};
nops:  要操作的信号灯的个数
  
所需头文件
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
函数原型
int semctl ( int semid, int semnum,  int cmd   union semun arg(不是地址 ) );
函数参数
semid :信号灯集 ID

semnum: 要修改的信号灯编号
 
cmd 
GETVAL :获取信号灯的值
SETVAL :设置信号灯的值
IPC_RMID :从系统中删除信号灯集合
 
 
函数返回值
成功: 0
 
出错: -1
semctl:cmd                          GETVAL:获取信号灯的值
                                            SETVAL:设置信号灯的值
                                            IPC_RMID:从系统中删除信号灯的集合
msgctl:cmd                          IPC_STAT(获取对象属性)
shmctl:cmd                          IPC_SET(设置对象属性)
SETVAL:设置信号灯的值  信号灯的初始化,类似sem_init;
联合体:                         
union semun
   {
          int val;  
//SETVAL:设置信号灯的值
          struct semid_ds *buf;
// IPC_STAT  (获取对象属性)
//IPC_SET (设置对象属性)
     unsigned short  *array;  /* Array for GETALL, SETALL */
     struct seminfo  *__buf;  /* Buffer for IPC_INFO (Linux-specific) */
   };
server.c端
#include "stdio.h"
#include "sys/ipc.h"
#include "sys/sem.h"
#include "sys/types.h"
#include "stdlib.h"
/*联合体*/
union semun
{
      int              val;   //SETVAL:设置信号灯的值  
      struct semid_ds *buf;   
      unsigned short  *array; 
      struct seminfo  *__buf; 
};
int main()
{
  int i;
  int key;
  int semid;
  union semun mysemun;
  struct sembuf mysembuf;
  key=ftok("./a.c",'a');//touch a.c记得每次要先创建a.c
  if(key < 0)
        return -1;
  semid=semget(key,2,IPC_CREAT | 0777);// 创建信号灯集
  if(semid < 0)
        return -2;
  mysemun.val=0;//初始化信号灯
  semctl(semid,0,SETVAL,mysemun);//初始化信号灯集,也可以删除信号灯;

   /*先运行*/
  for(i=0;i< 10 ;i++)
  {
    printf("this is first process\n");
      sleep(1);
  }
  /*运行完以后进行唤醒  v操作*/
  mysembuf.sem_num=0;
  mysembuf.sem_op=1;//信号灯v操作
  mysembuf.sem_flg=0;
  semop(semid,&mysembuf,1);
  return 0;
}
client.c端
#include "stdio.h"
#include "sys/ipc.h"
#include "sys/sem.h"
#include "sys/types.h"
#include "stdlib.h"

 union semun
{
      int              val;   
      struct semid_ds *buf;   
      unsigned short  *array; 
      struct seminfo  *__buf; 
};
int main()
{
  int i;
  int key;
  int semid;
  union semun mysemun;
  struct sembuf mysembuf;
  key=ftok("./a.c",'a');
  if(key < 0)
        return -1;
  semid=semget(key,2,IPC_CREAT | 0777);
  if(semid < 0)
        return -2;
  /*后运行不需要在初始化*/
  //mysemun.val=0;
  //semctl(semid,0,SETVAL,mysemun);
 
  //
  mysembuf.sem_num=0;
  mysembuf.sem_op=-1;//信号灯p操作
  mysembuf.sem_flg=0;
  semop(semid,&mysembuf,1);
  for(i=0;i< 10 ;i++)
  {
    printf("this is second process\n");
      sleep(1);
  }
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值