IPC 机制(sem、同步与异步)

声明

同步

同步,并发性不高;例如主函数中有子函数,子函数调用子函数,这样会一直调用函数,阻塞等待的过程。

这里写图片描述

异步

> 并发性高,例如多进程、多线程。

一旦设备准备好,就主动通知应用程序,这种情况下应用程序就不需要查询设备状态;异步是相对于同步而言,两个进程之间不影响,例如fork一个进程

进程同步机制

pipe、fifo、信号量(二值信号量)、共享类存、消息队列、以及Socket编程

线程同步机制

互斥锁、条件变量、读写锁、信号量

异步机制:

信号是进程间通信机制中唯一的异步通信机制;信号驱动的异步I/O,epoll是一种高效处理IO的异步

操作函数

这里写图片描述

这里写图片描述

打开和创建IPC流程

这里写图片描述

sem

声明:

信号量:信号量是一个整数值。单独使用没用,必须和资源结合,例如打印机、共享内存

知识点

1、包裹函数
2、key值
3、semget
4、semctl
5、semop
6、常用命令

1、包裹函数

对函数的简单包装,是程序看起来比较简洁,通常将函数名的第一个字母大写即可

//对semget()进行包裹
key_t Ftok(const char * pathname,int pro _id)
{
    key_t key =ftok(const pathname,pro_id)
    {
        ''''
    }
    return key;
}

2、key值

key值又称IPC键值,利用ftok函数来获得一个key,具有唯一性

//路径名 项目id
ket_t ftok(const char * pathname,int proj_id);

3、semget 打开、创建ipc

创建一个信号量集,或访问已存在的信号量集

//ipc键值  信号量集合(数组)   IPC_CREAT|IPC_EXCL|0755
int semget(key_t key,int nums,int oflag);

4、semctl

对信号量进行各种操作,获取信号量的值、设置信号量的值、删除信号量

    // id    信号量集合下表   getval  setval ipc_rmid
int semctl(int semid,int semmum,int cmd...)

5、semop

对信号量的操作,例如加减

// id  结构体的地址  数组元素个数 number
int semop(int semid,struct sembuf *opsptr,siez_t nops);

//结构体使用时,直接定义结构体类型的对象即可
//联合体使用时,必须声明联合体类型,才可以定义对象

struct sembuf
{
    short sem_num;//集合下表
    short sem_op //>0 加  <0 减
    short sem_flg; 0 默认
};

6、常用命令

1、ipcs -s 查看信号量
2、ipcrm -s id 删除信号量

实现

  1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<sys/ipc.h>
  4 #include<sys/sem.h>
  5 #include<stdlib.h>
  6 int main()
  7 {
          //获取ipc键值
  8     key_t key = ftok("../yourfile",0xffee);
  9     if(key == -1)
 10     {
 11         perror("Ftok key");
 12         exit(1);
 13     }
 14     else
 15         printf("key =%x\n",key);
     16      //获取id号
 17     int sem_id = semget(key,1,IPC_CREAT|0755);
 18     if(sem_id == -1)
 19     {
 20         perror("IPC creat");
 21         exit(1);
 22     }
 23     else
 24         printf("sem_id = %d\n",sem_id);
 25     //set init val
 26     union semun
 27     {
 28         int val;
 29         struct semid_ds *buf;
 30         unsigned short *array;
 31         struct seminfo *__buf;
 32     };
         //初始化
 33     union semun info;
 34     info.val = 3;
 35     int re=semctl(sem_id,0,SETVAL,info );
 36     if(re == -1)
 37     {
 38         perror("set val");
 39     }
 40     else
 41         printf("init val success.\n");
 42     //get val
 43     int res = semctl(sem_id,0,GETVAL);
 44     if(res == -1)
 45     {
 46         perror("getval ");
 47     }
 48     else
 49         printf("val =%d\n",res);
 50     //op sem
 51     struct sembuf op;
 52     op.sem_num = 0;
 53     op.sem_op = 2;
 54     op.sem_flg = 0;
 55     int value;
 56     value= semop(sem_id,&op,1);
 57     if(value == -1)
 58     {
 59         perror("op error.");
 60     }
 61     else
 62         printf(" semop success.\n");
 63 
 64 
 65     //get val
 66      res = semctl(sem_id,0,GETVAL);
 67     if(res == -1)
 68     {
 69         perror("getval ");
 70     }
 71     else
 72         printf("val =%d\n",res);
 73     //ipsrm 
 74      res = semctl(sem_id,0,IPC_RMID);
 75     if(res == -1)
 76     {
 77         printf("Remove sem fail\n");
 78     }
 79     else
 80         printf("Remove sem success\n");
 81 
 82     return 0;
 83 }

结果:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值