【无标题】

5 篇文章 0 订阅
5 篇文章 0 订阅

day3
进程间通信–>无名管道 有名管道 信号通信
p
共享内存 消息队列 信号灯 socket

通信领域的几个概念:
单工通信:数据的传送方向为单向
半双工通信:数据的传送方向为双向,但不同时
全双工通信:数据的传送方向为双向,且同时进行
在这里插入图片描述在这里插入图片描述1、无名管道:
无名管道是用pipe创建的一个内核文件,用于具有亲缘关系的进程间的通信,无名管道多用于单工通信

int pipe(int pipefd[2]);

pipefd[2]:数组,pipefd[0]用来标识读管道文件
pipefd[1]用来标识写管道文件
返回值:0成功;-1失败
特点:
1、只能用于具有亲缘关系的进程间通信
2、是一种单工通信模式,理论上是双工的,但是通信双方的收发顺序不好控制,通常用作单工
3、无名管道的数据存放在内存中,管道中的数据读走后,就不存在了,无名管道只存在于内核中,在文件系统中不可见
函数库: 动态库和静态库
1、 .so .a
2、使用时刻不同,运行 编译
3、 可移植性
1、有名管道:
有名管道是用mkfifo创建的一个内核文件用于任意两个进程之间的通信,管道文件在文件系统中可见

int mkfifo(const char *pathname, mode_t mode);

作用:创建一个有名管道文件
*pathname:有名管道文件的名称
mode:文件权限
返回值:成功0;失败-1

ret  = mkfifo("fifo",0666);

if(ret<0 && EEXIST!=errno)–>创建文件失败,并且该文件之前不存在
{
return -1;//创建失败
}
创建文件失败但是该文件存在–>创建文件成功
特点:
1、有名管道可以用于任意两个进程间的通信
2、可以实现双工通信(需要两个管道文件)
3、有名管道中的数据存放在内存中,有名管道中的文件在文件系统中可见,管道中的文件读走后就不存在了,文件大小为0,文件数据存放在内存中

3、信号通信
异步通信:被通信方不知道通信方什么时候跟它通信
同步通信发送方发送数据,接收方接收数据,双方需要在很短的时间内完成数据交换,否则会造成一方阻塞。
信号:是对中断的模拟,信号通信是一种异步通信方式,是一个通知
中断:是指CPU在执行程序的过程中插入了另外一段程序的过程

信号:linux操作系统与预先定义好了64个信号
kill -l 查看当前系统提供的所有信号
kill -9 进程号:给内核发送SIGKILL信号,让内核杀死指定进程
用户进程对信号的响应方式:
1、捕获信号
2、忽略信号
3、采用默认处理动作
signal(信号,自定义的信号对应的处理函数)–>用来改变一个信号对应的默认处理动作
分析两个进程的异步通信–>alarm_test.c
实现两个进程的异步通信:
A:收信号进程:signal pause
B:发信号进程:kill()

int kill(pid_t pid,int sig);

参数1:pid:对方进程号
参数2:sig:发信号

A:
1: mkfifo–>有名称
2 :open
3: write
B:
1: mkfifo
2:open
3:read

在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
进程间通信:共享内存 消息队列 信号灯
1、共享内存:
A:1 ftok(“.”,int a) -->生成一个标识符
2 shmget–>
3 shmat
4 mencpy

B:1 ftok
2 shmget
3 shmat
4printf();

key_t ftok(const char *pathname, int proj_id);

作用:生成对方进程找到自己的标识符
*pathname:用户指定的路径,可以是“.”,或“、“/home/fartsight/…”
proj_id:0~255
返回值:成功得到的一个唯一的key值,失败-1

int shmget(key_t key, size_t size, int shmflg);

作用:创建一块共享内存
参数1:key:IPC_PRIVATE或ftok的返回值
参数2:sizeBULL:共享内存的大小
参数3:shmflg:操作共享内存的权限|IPC_CREAT
返回值:成功shmID–>标识创建成功的共享内存,失败-1

void *shmat(int shmid, const void *shmaddr, int shmflg);

作用:将本地内存和共享内训建立映射
参数1:shmid:共享内存的标识符,shmget的返回值
参数2:*shmaddr:指向本地内存地址的指针,一般给BULL。
参数3:shmflg:SHM_RDONLY–>共享内存只读
0–>共享内存可读写
返回值:指向映射成功后的本地内存地址

int shmdt(const void *shmaddr);

作用:取消映射
*shmaddr:映射成功后的本地内存地址,shmat的返回值

int shmctl(int shmid,int cmd,struct shmid_ds *buf);

作用:设置或获取共享内存属性
shmid:共享内存的标识符 shmget的返回值
cmd:操作选项:IPC_STAT(获取对象属性)
IPC_SET(设置对象属性)
IPC_RMID(删除对象)
*buf:指向共享内存的属性值,IPC_STAT或IPC_STAST或IPC_SET时使用,IPC_RMID时该值为NULL
2、消息队列
A:
1:ftok
2:msgget
3:创建消息结点
4:msgsnd–>发消息 -->ipcs查看消息
B:
1:ftok
2:msgget
3:msgrcv

int msgget(key_t key, int msgflg);

作用:创建一个消息队列
参数1: key:ftok的返回值
参数2:msgfly:IPC_CREAT|访问权限
返回值:成功消息队列ID,失败-1
消息结点:一般有消息类型和消息正文组成
struct msgbuf
{
long m_type;//消息类型
char buf[BUF_SIZE];//消息正文,BUF_SIZE消息大小
}

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);

作用:给消息队列发消息
参数1:msqid:消息队列ID
参数2:msgp:指向消息结构体的指针
参数3: size_t msgsz:消息正文数组的大小
参数4:msgfly:IPC_NOWAIT:消息没有发送完成函数也会立即返回,
0:直接发送完成函数才返回
返回值:0成功,-1失败

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);

作用:从消息队列读取消息
参数1:msqid:消息队列ID
参数2:msgp:指向消息结构体的指针
参数3: size_t msgsz:消息正文数组的大小
参数4:msgtype:0:接受 消息队列中的第一个消息
大于0:按照消息类型接收消息(若同类型的消息有多个,先进先出原则)
返回值:成功,期望接收到的消息长度(而非实际接收到的消息长度),失败-1

3、信号灯
Linux提供了三种信号灯:
1、无名信号灯–>sem_t sema;–>用于线程间同步
2、有名信号灯–>sem_open–>用于进程间同步
3、信号灯集(system V信号灯)–>多个信号灯的集合–>用于多个进程或线程间的同步
信号灯:也叫信号量

int semget(key_t key, int nsems, int semflg);

作用:
参数1:
参数2:
参数3:
返回值:

int semop(int semid, struct sembuf *sops, size_t nsops);

作用:
参数1:
参数2:
参数3:
返回值:
在这里插入图片描述int semctl(int semid, int semnum, int cmd, ...);
作用:
参数1:
参数2:
参数3:
返回值:
在这里插入图片描述
在这里插入图片描述sem_t *sem_open(const char *name, int oflag,mode_t mode, unsigned int value);
作用:创建有名信号灯
参数1:*name:信号灯的名称
参数2:oflag:动作控制参数O_CREAT O_EXCL
参数3:mode:权限
参数4:value:信号灯的初值
返回值:指向创建成功的信号灯

消息队列实现收发消息

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值