声明
同步
同步,并发性不高;例如主函数中有子函数,子函数调用子函数,这样会一直调用函数,阻塞等待的过程。
异步
> 并发性高,例如多进程、多线程。
一旦设备准备好,就主动通知应用程序,这种情况下应用程序就不需要查询设备状态;异步是相对于同步而言,两个进程之间不影响,例如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 }
结果: