进程间通讯方式(IPC)::无名管道 有名管道 信号量 共享内存 消息队列 信号 套接字 多机通讯
1、有名管道:: 在文件目录树中创建一个文件标识(管道文件),实际不占据磁盘空间,在内存上进行,应用于任意两个进程之间数据单向链接;在使用时,在内存上开辟一段空间,A传给B,A写B读,读过的数据就被销毁了,不会保存。
创建:命令方式 mkfifo 函数方式 mkfifo();
打开:open
读写数据:read,write
关闭:close
2、无名管道::相对于有名管道而言,无名管道在使用时产生,不使用后释放,并不会在系统留下任何痕迹。因为没有留下任何标志,所以只能用于父子进程之间。原因:子进程会复制父进程的文件表数组,而且是浅拷贝。
创建: int pipe( int fd[2]); fd[0] 读 fd[1] 写
打开: int pipe( int fd[2]); fd[0] 读 fd[1] 写
读: read(fd[0],buff,size);
写: close(fd[1],buff,size);
关闭:close(fd[1]); close(fd[0]);
注意:管道都是半双工通信,而无名管道创建后,父进程在fork产生子进程后,两个进程分别有一对读写,所以要在父子进程分别关闭。
fd[0]/fd[1] 都是文件描述符, 无名管道创建:int fd[2]; pipe(fd);
3、信号量::
计数器,记录资源同一时间能被进程使用(进程在使用时,进行减一操作,用完后加一)
临界资源,同一时刻只能被一个进程访问的资源。
临界区,访问临界资源的代码区域。
原子操作,任何情况下都不能被打断的操作(不可分割的操作)。
内核对象,用于对进程间通讯时,多进程能够访问同一资源的记录。
信号量的作用,进程间同步控制。
信号量的操作:
创建或获取:如果是创建,必须初始化;如果获取,则不能初始化。
减一操作:p操作
加一操作:v操作
删除
函数: int semget((key_t) key, int nsems, int flag);//获取信号量ID
int semctl(int semid, int senum, int cmd,/*union semun arg*/);//信号量操作,使用信号量
int semop(int semid, struct sembuf* buff, int length);//设置pv操作,自动执行信号量集合上的操作数组,原子操作
函数封装:
int semid = 0;
void seminit()
{
semid = semget((key_t)1234,1,0666);//创建信号量
if(semid == -1)
{
semid = semget((key_t)1234,1,0666|IPC_CREAT);
if(semid == -1)
{
perror("");
exit(0);
}
union semun v;
v.val = 0;//val==0; a和b为服务关系
//val==1; a和b为竞争关系
semctl(semid,0,SETVAL,v);//将semid设置成v操作
}
}
void sem_p()
{
struct sembuf buf;
buf.sem_num = 0;
buf.sem_op = -1;//减一操作
buf.semflag = SEM_UNDO;//使操作系统跟踪信号,并在进程没有释放该信号量而终止,操作系统释放信号量
semop(semid,&buf,1);
}
void sem_v()
{
struct sembuf buf;
buf.sem_num = 0;
buf.sem_op = 1;
buf.sem_flg = SEM_UNDO;
semop(semid,&buf,1);
}
void sem_del()
{
semctl(semid,0,IPC_RMID,NULL);//IPC_RMID删除一个不需要的信号量标识符
}
4、信号::是一种比较复杂的通信方式,用于通知接收某个事件已经发生。
5、消息队列::
消息:数据+类型
队列:数据结构,先进先出
消息队列:是一种临时存储消息的队列,完成进程间数据传递,而是有优先级的队列。
特点:与信号量对比:都以内核为对象来确保多进程访问同一个消息队列,信号量进行进程同步控制,消息队列发送实际数据,
与管道相比:管道发送的数据没有类型,读取数据端无差别,从管道中按照数据的前后顺序,消息队列数据有类型,读端可以根据数据类型读取特定数据。
6、共享内存:由内核对象来管理共享的区域内存。
特点:共享内存是最快的一种IPC,在各个进程都有指针直接指向开辟的内存区域,访问时当本进程中的一个内存控制直接操作。
注意:共享内存是两个以上的进程能够操作的一块物理空间的内存区域,所以共享区域就成了临界资源,所以对于共享区域的访问必须做同步控制。
7、套接字通讯::套接口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同机器间的进程通信。