linux之--进程间通信
进程间通信也就是IPC
主要方式有:管道通信(无名,FIFO)、消息队列、共享内存、信号、信号量等等。
还有socket、streams还暂时未学到
1.管道(无名)
#include <unistd.h>
int pipe(int pipefd[2]);
这是一种半双工通信,只能一端来收,一端发;
fd[0]是读端,fd[1]是写端
通过无名管道进行通信时,必须只能读或写;
2.有名管道FIFO
首先创建mkfifo一个名字为file1的管道,可读可写;接下来打开管道读取或写入。
3.消息队列(链表的形式)
收:
发:
消息队列有一个结构图struct msgbuf,这个以后会经常用到,mtype一般可设为888,mtext为字符串内容;
key的获取用ftok(".",1);
主要操作为获取队列id,用msgget(key,IPC_CREAT|0777)// 通用格式;
消息队列收发:
msgrcv(msgid,&newget,sizeof(newget.mtext),888,0);相比snd多一个参数
msgsnd(msgid,&newsend,sizeof(newsend.mtext),0);
删除队列
msgctl(msgid,IPC_RMID,NULL);//通用
4.共享内存
读:
共享内存时一个可以实现同时读取和写入的操作,比较高级,用的也比较广泛一些。
其操作步骤为:
1.创建共享内存;int shmid = shmget(key,4*1024,IPC_CREAT|0666);
2.映射到各自内存空间;p = shmat(shmid,0,0);
3.断开映射;shmdt§;
4.释放内存;shmctl(shmid,IPC_RMID,NULL);
写:
补充:ipcs -m 查看系统的共享内存
ipcsrm -m id 删除id这个共享内存
5.信号
它是一种软中断;
信号分为入门操作和高级操作;
通过kill -l 查看信号有64种,2退出,9强退,10用的较多
(1).初级
发:
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
收:
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);// handler是函数指针
下面为简单的信号中断实验:
让SIGINT无法运行;
通过kill执行signum操作(9为强制退出)。
(2)高级:信号发送时可以携带数据(例如数字或字符串)
**发:**sigqueue()
**收:**sigaction()
6.信号量
信号量是一种功能,它不涉及数据,只涉及开关通道,类似一把锁,掌握开门关门。
P操作:拿锁
V操作:还锁
以下为主要API:
int semop(int semid, struct sembuf *sops, size_t nsops);
int semget(key_t key, int nsems, int semflg);获得描述符
int semctl(int semid, int semnum, int cmd, …);//执行指令(SETVAL)
delsem(semid);删除信号量
该程序设置锁的初值set.val = 0;为0,没拿到钥匙通道不开启,进而创建一个子进程,先换钥匙,进而父进程可以拿到钥匙开锁,执行程序;