进程间通信--Linux


进程间通信(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);//获取消息

共享内存 消息队列都是在内存中创建

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值