1.8io网络

同步机制条件变量

1> 条件变量本质上也是一个临界资源,维护了一个队列,当消费者要想指向前,先进入等待队列中,直到生产者唤醒后,才能执行

2> 由于多个消费者线程要进入等待队列时,可能产生竞态,为了解决该竞态,同样要引入互斥机制

3> 条件变量表示一个生产者和多个消费者之间的同步关系,而消费者和消费者之间没有同步关系

条件变量的API

创建条件变量

初始化条件变量

消费者线程进入等待队列

唤醒消费者线程

销毁条件变量

进程间的通信

通信概念

1> 多个线程之间的信息通信可以使用全局变量来完成,只需注意同步互斥机制即可

2> 多个进程之间的信息通信,不可用使用全局变量完成,因为多个进程之间用户空间是独立的,每个进程拥有自己的全局变量

3> 可以使用外部文件完成多个进程之间通信,一个进程向文件中写入数据,另一个进程从文件中读取数据。但是由于进程的调度是时间片轮询机制,不确定哪个进程先执行,所以该方案需要在多进程同步的基础上完成

4> 由于多个进程之间用户空间是独立的,但是内核空间是共享的,所以可以利用内核空间完成通信,一个进程向内核空间写入数据,另一个进程可以从内核空间取出数据

1.8io网络_第1张图片

通信方式

1、内核提供了三种通信方式:无名管道、有名管道、信号

2、System V提供了三种通信方式:消息队列、共享内存、信号量(信号灯集)

3、套接字通信

管道

1> 在内核空间创建出一个特殊的文件(管道文件)

2> 对于管道文件中的数据操作是一次性的,当管道中的数据被读取后,就不存在了

3> 管道分为无名管道和有名管道:无名管道仅用于亲缘进程间的通信,而有名管道,既可以用于亲缘进程间通信,也可以用于非亲缘进程间通信

4> 管道的通信是半双工通信方式:

单工:只能A进程向B进程发送数据

半双工:同一时刻,只能A向B发数据或B向A发数据

全双工:同一时刻,AB进程可以互发消息

5> 管道遵循先进先出的原则:先写入的数据会先读取出来

6> 一个管道被打开后,会产生两端,分别是读端和写端,当两端全部都被关闭后,管道在内核中就消失了

7> 由于管道存在内核空间,对管道的操作只能使用系统调用(文件IO),而且不能使用lseek移动光标

无名管道

1> 无名管道:顾名思义就是没有名字的管道,不存在于文件系统中,管道文件创建出来后,在内存中存放

2> 由于在内存中存放,没有文件系统中的名字,所以,一个进程创建出来的无名管道文件,其他进程是没有办法打开的,所以该方式不适用于非亲缘进程间通信

3> 无名管道,只适用于亲缘进程间通信,并且,需要在创建子进程之前将管道文件打开

4> 无名管道的api

#include

int pipe(int pipefd[2]);

5> 管道的特性

1、可以使用无名管道完成自己跟自己通信

2、管道的大小为:64K

3、管道的读写特点

当读端存在时:写管道有多少写多少,直到写满64k后,在write处阻塞

当读端不存在时:写管道写入数据后,会导致管道破裂

当写端存在时:读管道有多少读多少,没有数据的话,在read处阻塞

当写端不存在时:读管道有多少读多少,没有数据的话,不会在read处阻塞

有名管道

1> 有名管道:顾名思义就是有名字的管道,存储在文件系统中

2> 有名管道的操作也是一次性的,数据被读取后,就没有了

3> 虽然存储在外部磁盘上,但是,不用于存储信息,只是用于进程间通信

4> 有名管道既可以用于亲缘进程间通信,也可以用于非亲缘进程间的通信

5> 有名管道的api5> 有名管道的api

#include

#include

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

信号

信号基本概念

1> 信号是软件模拟硬件中的中断,中断是硬件实现的,信号是软件实现的

2> 中断:停止当前正在进行的事情,去执行其他事情,执行结束后,继续执行自己的事

3> 一个进程可以给另一个进程发送信号;用户也可以给一个进程发送信号;内核可以向进程发送信号

4> 信号通信,属于异步通信:两个进程各干各的,互不影响

5> 信号处理方式:默认(一般是杀死进程)、忽略、捕获(捕获信号去做另一件事)

信号的种类及功能

信号绑定函数(signal)

#include

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

信号发送函数(kill、raise)

#include

int kill(pid_t pid, int sig);

#include

int raise(int sig);

System V进程间通信(IPC对象)

1> 种类:

消息队列:在内核空间维护了一个队列,所有进程都可以向队列中存放数据,也可以从队列中取出数据

共享内存:将物理内存映射出来,共所有进程使用

信号量(信号灯集):主要完成进程的同步工作

2> 关于IPC的相关指令

ipcs: 查看所有IPC对象的详细信息

ipcs -q:只查看消息队列的详细信息

ipcs -m:只查看共享内存的详细信息

ipcs -s:只查看信号量的详细信息

ipcrm -q/-m/-s ID:表示删除指定的消息队列、共享内存、信号量

3> 关于系统5提供的进程间通信对象,都需要使用一个key值

消息队列

1.8io网络_第2张图片

消息队列的API

1、创建key值

2、创建消息队列

3、向消息队列中存放数据

4、从消息队列中取消息

5、消息队列的控制函数

共享内存

1> 所谓共享内存,是将物理内存映射到不同的进程中,不同进程直接对映射出来的共享内存进行操作,无需进行用户空间和内核空间的切换

1.8io网络_第3张图片

共享内存的相关API

1、创建key值

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

2、申请物理内存,创建出共享内存段2、申请物理内存,创建出共享内存段

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

3、将共享内存映射到用户空间

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

4、取消共享内存的映射

int shmdt(const void *shmaddr);

5、共享内存的控制函数

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

你可能感兴趣的:(笔记)