linux进程简介三 进程间通信

本文深入探讨了Linux进程间通信的基础概念和常见方式,包括信号、信号量、共享内存、管道、消息队列以及Socket通信机制。详细介绍了各种通信方式的特点和使用场景,如信号的软中断性质、信号量的同步与互斥功能、管道的半双工特性以及Socket在网络通信中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文来梳理下进程间通信的必备知识。

基础概念

并发进程之间的交互必须满足两个基本要求:同步和通信。

并发进程之间的两种关系:竞争与协作。(用互斥解决竞争关系,用同步解决协作关系)


进程同步:指两个以上进程基于某个条件来协调它们之间的活动。(说的简单点,就是为了共同的任务,需要进程排着队,一个个来处理)

进程互斥:指若干个进程要使用同一个共享资源时,在任何时刻只允许一个进程使用,其它的都得等待。

互斥是进程同步的特例。


进程间通信的方式:

  1. 信号通信机制:signal
  2. 信号量与P/V操作
  3. 共享内存通信机制
  4. 消息队列传递通信机制
  5. socket 单机/网络通信机制

信号

别名软中断,通常用来处理可以延时的任务,比如tcp/ip操作,SCSI协议操作等。

信号量

组成元素:一个变量、一个进程等待队列。

信号量加上P/V操作可用来解决进程间的同步与互斥问题,不过仅限传递信号,并没有传递数据的能力。

两大种类:system v版本的信号量只能用于进程,而POSIX版的可同时用于进程与线程。

参考 https://blog.youkuaiyun.com/lh2016rocky/article/details/70800958

管道pipe

我们所提的管道主要指无名管道,还有一种叫做named pipe

它有几大特点:

  • 只能用于亲缘关系的进程间通信(父子or兄弟关系)
  • 半双工通信,有固定的读端和写端
  • 可被看成一种特殊的文件(实际为内核的一个缓冲区),用read和wirte函数读写。
int pipe(int pipefd[2]);

用pipe创建管道时会有两个文件描述符,其中 pipefd[0] 固定用来读,pipefd[1] 用来写。

创建管道流程:

管道几个注意点:

  1. 只有在管道的读端存在时,向管道写入数据才有意义。否则,向管道写入数据的进程将收到内核传来的SIGPIPE 信号(通常为Broken pipe 错误)。
  2. 向管道写入数据时,Linux 将不保证写入的原子性,管道缓冲区一有空闲区域,写进程就会试图向管道写入数据。如果读进程不读取管道缓冲区中的数据,那么写操作将会一直阻塞。

命名管道特点:

  1. 可以使互不相关的两个进程实现彼此通信

 

 

代码参考  https://github.com/allen605/os_study/tree/master/pipe_folder

消息

 

socket

POSIX标准所规定的 socket api是基于BSD版的socket api。(BSD是一个unix系统的分支,由伯克利分校开发与维护)

 

扩展:线程的互斥与同步

linux系统遵循POSIX标准,所以本文只考虑使用POSIX的api。

因为线程之间可以共享进程的数据(不像IPC那么复杂),所以只需关注同步问题即可。


互斥量:是一个用来保证线程在关键区正常执行的变量。

pthread_mutex_t pthread_mutex_lock(pthread_mutex_t  *mutex);

检查互斥量mutex是否上锁,如果已经上锁,则会进入阻塞态。

条件变量:是一个特殊的线程结构体变量,它可以允许一个线程等待某一个事件,另一个线程在事件发生时向它发送信号。

//等待某一事件
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
//发出信号
int pthread_cond_signal(pthread_cond_t *cond);

条件变量需要和互斥量配合使用。当调用wait时,会进入阻塞态并自动解锁,直到收到信号后进入运行态并自动上锁,继续往下运行。

代码参考 pthread_cond_mutex_os.c  https://github.com/allen605/os_study


POSIX信号量:

int sem_init(sem_t *sem, int pshared, unsigned int value);

int sem_wait(sem_t *sem);
int sem_trywait(sem_t *sem);  //not blocked
int sem_post(sem_t *sem);    //increments (unlocks) the semaphore.
int sem_getvalue(sem_t *sem, int *sval);

其和传统的P/V操作类似,sem_wait() 即P操作,用来申请共享资源;sem_post即V操作,用来释放资源。

信号量参考 https://blog.youkuaiyun.com/lh2016rocky/article/details/70800958

<ing>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值