linux 高级编程

本文介绍了Linux系统中的进程间通信方式,包括管道(半双工和全双工)、命名管道FIFO、消息队列、信号量和共享内存。详细讲解了每种通信方式的特点和使用场景,如管道适用于父子进程通信,消息队列允许无亲缘关系的进程通信,信号量用于资源访问控制和同步,共享内存则提供了快速的数据交换途径。

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

进程间通信(IPC:InterProcess Communication)

1 管道:

    半双工管道:即数据只能在一个方向上流动(历史上管道是半双工的,现在的系统提供全双工管道,但是为了最佳的移植性,建议使用半双工管道)

    管道只能在具有公共祖先的进程间使用:通常:一个管道由一个进程调用pipe创建,然后该进程调用fork,这样父子进程就可以应用该管道。 

    int fd[2] ;

    读端:fd[0]

    写端:fd[1]

    创建管道:pipe(fd);

    父进程:关闭读端close(fd[0]); 写入数据到写端:wtrte(fd[1], "hello world\n", 12);

    子进程:关闭写端close(fd[1]); 读出数据从读端:read(fd[0], str, 12); 

2 命名管道 FIFO

    mkfifo创建FIFO文件,FIFO文件真实存在系统中,通过FIFO文件,不具有亲缘关系的进程可以实现通信。

3 消息队列

    对消息队列有写权限的进程可以向中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息(创建的时候设置权限)。消息队列是随内核持续的,只有在内核重起或者显示删除一个消息队列时,该消息队列才会真正被删除。因此系统中记录消息队列的数据结构(struct ipc_ids msg_ids)位于内核中,系统中的所有消息队列都可以在结构msg_ids中找到访问入口。

    这种消息的发送方式是:发送方不必等待接收方检查它所收到的消息就可以继续工作下去,而接收方如果没有收到消息也不需等待。

4 信号量

    他是一个计数器,用于多进程对共享资源的访问,同时也用于进程同步。

    一般说来,信号量的初值可以是任意正值,该值说明有多少个共享资源单位可以共享,为了获取共享资源,进程需要执行以下操作:

1 测试控制该资源的信号量

2 若此信号量为正,那么进程可以使用该资源。进程将信号量值减1,表示他使用了一个资源单位

3 若此信号量值为0,则进程进入休眠状态,直到信号量大于0,进程被唤醒,返回第1步

    当进程不再使用由一个信号量控制的共享资源时,该信号量值加1,如果有进程正在休眠等待此信号量,唤醒他们

5 共享内存

    多个进程对同一块内存空间进行存储的区域。是一种最快的IPC。信号>量通常被用来实现共享存储的同步。

一个终端的进程创建一块共享存储区域,往区域内写入hello world,然后退出(不能关>闭掉共享存储区); 另一个终端的进程链接到共享存储区,并且从共享存储区内读入hello world

线程间通信:所有进程间通信的方式

自旋锁实际上是忙等锁,当锁不可用时,CPU一直循环执行测试并设置(test-and-set)”该锁直到可用而取得该锁,CPU在等待自旋锁时不做任何有用的工作,仅仅是等待。这说明只有在占用锁的时间极短的情况下,使用自旋锁是合理的,因为此时某个CPU可能正在等待这个自旋锁。当临界区较为短小时,如只是为了保证对数据修改的原子性,常用自旋锁;当临界区很大,或有共享设备的时候,需要较长时间占用锁,使用自旋锁就不是一个很好的选择,会降低CPU的效率。
   
自旋锁也存在死锁(deadlock)问题。引发这个问题最常见的情况是要求递归使用一个自旋锁,即如果一个已经拥有某个自旋锁的CPU想第二次获得这个自旋锁,则该CPU将死锁。

只有当进程占用资源很长时间时,用信号量才是不错的选择。
   
当所要保护的临界区比较短时,用自旋锁是非常方便的,因为它节省上下文切换的时间。但是CPU得不到自旋锁会在那里空转直到锁成功为止,所以要求锁不能在临界区里停留很长时间,否则会降低系统的效率

自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环查看是否该自旋锁的保持者已经释放了锁,“自旋”就是“在原地打转”。而信号量则引起调用者睡眠,它把进程从运行队列上拖出去,CPU不会停,会接着运行其他的执行路径。 但是,无论是信号量,还是自旋锁,在任何时刻,最多只能有一个保持者,即在任何时刻最多只能有一个执行单元获得锁。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值