进程间通信(IPC): 管道 信号量 消息队列 共享内存 套接字
管道:
有名管道:任意间进程,无名管道:父子间进程
有名管道 无名管道 区别:是否在父子进程间通信
创建方式:
1.mkfifo 创建管道
2.mkfifo()系统调用
调用函数:open(fd, 文件名 );//已知文件,需三个参数,还有文件路径,新建文件,即为当前目录,则不需
write() read() close()
文件描述符 fd
pipe()创建无名管道,只能用在父子管道间,有名管道任意两个进程间
文件描述符:fd[o]读,fd[1]写
dup2()重定向,把输出改变位置
管道属于半双工通信模式。
写入管道文件的数据在内存中存放,有名管道文件的大小为0.
eg: dup2(fdw,1);//1代表屏幕标准输出,新文件代替屏幕输出
(1)管道为空,读read阻塞
(2)管道为满,写write阻塞
管道文件 类型为p,大小为0
简述管道:内存分配管道空间,管道把内存空间分成一个一个字节,内存自动分配头指针,尾指针,头指针与尾指针之间距离即管道当前数据大小,头指针为写,尾指针为读。内存满,则不再写,尾指针指向头指针,则读完。
管道的读关闭,系统默认则写关闭。用signal(SIGPIPE,fun);//调用信号,写端程序不会退出。则程序退出一定是传递信号。
三种响应方式:1.默认 SIG_DFL
2.忽略 SIG_IGN
3.自定义 fun()
SIGCHLD处理僵尸进程(子进程结束)发送给父进程
#include<fcntl.h>
查找命令:ps -ef | grep "bash"// |管道 grep过滤 名字为bash的文件
《Linux 程序设计》第13章
信号量
同步进程:受临界资源控制的进程
临界资源:同一时刻,只允许一个进程访问的资源
临界区:访问临界资源的代码段
原子操作 :P V操作
信号量:特殊的变量,值的改变是原子操作。 只能进行加减1的操作,二进制信号量。
取整数值:二值信号量 0,1
计数信号量:信号量为3
信号量的值表示访问临界资源的数目
p减1获取资源,当值为0时,执行p操作会阻塞。v加1释放资源
相关函数:
#include<sys/sem.h>
union semun
{
int val
};
void sem_init()
{
semid = semget((key_t)1234,1,IPC_CREAT|IPC_EXCL|0600);
if(semid == -1)
{
semid = semget((key_t)1234,1,0600);
if(semid == -1)
{
printf(“semget error");
}
}
else
{
union semun a;
a.val = 1;
if(semctl(semid,0,SETVAL,a) == -1)
{
perror("semctl error");
}
}
}
void sem_p()
{
struct sembuf buf;
buf.sem_num = 0;
buf.sem_op = -1;//p操作
buf.sem_flg = SEM_UNDO;
if(semop(semid,&buf,1) == -1)
{
perror("semop p error");
}
}
void sem_destroy()
{
if(semtcl(semid,0,IPC_RMID) == -1)
{
perror("semctl error");
}
}
int semctl(int sem_id,int sem_num,int command,……);//控制信号量 初始化,以及删除操作
int semget(key_t key,int num_sems,int sem_flags);//创建信号量,或者取现有信号量的值
int semop(int sem_id,struct *sem_ops,size_t num_sem_ops);//执行pv操作,根据参数来判断
查看:ipcs -s 信号量id
-m 共享内存
-q 消息队列
删除:ipcrm -s +id 信号量
-m
-q
共享内存:
共享内存:物理地址同时被映射到a进程,b进程
#include<sys/shm.h>
void *shmat(int shm_id,const void *shm_addr,int shmflg);//映射内存空间
char *s = (char *)shmat(shmid,NULL,0);
int shmctl(int shm_id,int cmd,struct shmid_ds *buf);//控制共享内存,删除空间
int shmdt(const void *shm_addr);//断开映射,此进程不再访问而已,内存空间还在,其他进程还可以访问
shmdt(s);
int shmget(key_t key,size_t,int shmflg);//创建共享内存,或者获取已存在的空间
int shmid = shmget((key_t)1234,256,IPC_CREAT|0600);
过程需要信号量来控制,使得a程序,b程序通过共享内存来通信。a写入,共享内存,b读
《Linux 程序设计》第14章
消息队列:
消息为结构体,有大小,有类型(大于等于1的值)
要自己写结构体:(类似信号量)
struct message
{
long int type;//long int 固定类型
char buff[32];
};
int msgid = msgget((key_t)1234,IPC_CREAT|0600);//创建消息队列
struct message dt;消息类型为1
strcpy(dt.buff,"hello1");
msgsnd(msgid,&dt,32,0);//添加消息
dt.type = 1;//
msgrcv(msgid ,&dt,32,1,0);//获取消息
共享内存 消息队列都是在内存中创建