大家好,欢迎来到IT知识分享网。
进程通信和线程通信:
1.进程间通信:
①管道
管道传输数据是单向的,如果想相互通信,我们需要创建两个管道才行,半双工。
1.匿名管道,
用完销毁。int pipe(int fd[2])
⼀个是管道的读取端描述符 fd[0] ,另⼀个是管道的写⼊端描述符 fd[1] 。注意,这个匿名管道是特殊的文件,只存在于内存,不存于文件系统中。通信的数据是无格式的流并且大小受限。
2.命名管道:
因为数据是先进先出的传输方式。
管道这种通信方式效率低,不适合进程间频繁地交换数据;
所谓的管道,就是内核里面的⼀串缓存。从管道的⼀段写⼊的数据,实际上是缓存在内核中的,另⼀端读取,也就是从内核中读取这段数据。
最后:
- 我们可以得知,对于匿名管道,它的通信范围是存在父子关系的进程。因为管道没有实体,也就是没有管道文件,只能通过 fork来复制父进程 fd 文件描述符,来达到通信的目的。
- 另外,对于命名管道,它可以在不相关的进程间也能相互通信。因为命令管道,提前创建了⼀个类型为管道的设备文件,在进程里只要使用这个设备文件,就可以相互通信。
②消息队列:
基本原理:A 进程要给 B 进程发送消息,A 进程把数据放在对应的消息队列后就可以正常返回了,B 进程需要的时候再去读取数据就可以了。
特点:
- 消息队列是保存在内核中的消息链表,每个消息体都是固定大小的存储块。如果进程从消息队列中读取了消息体,内核就会把这个消息体删除。
- 如果没有释放消息队列或者没有关闭操作系统,消息队列会⼀直存在。
缺点:
- 通信不及时,附件也有大小限制。
- 消息队列不适合比较大数据的传输,每个消息体都有⼀个最大长度的限制,同时所有队列所包含的全部消息体的总长度也是有上限。
- 消息队列通信过程中,存在用户态与内核态之间的数据拷贝开销。
③共享内存:
共享内存解决了消息队列的读取和写⼊的过程会有发生用户态与内核态之间的消息拷贝的问题。
就是拿出⼀块虚拟地址空间来,映射到相同的物理内存中。这段共享内存由一个进程创建,但多个进程都可以访问。这样这个进程写⼊的东⻄,另外⼀个进程马上就能看到了,都不需要拷贝,提高了进程间通信的速度。
④信号量:
- 防止多进程竞争共享资源,造成的数据错乱,所以需要保护机制,使得共享的资源,在任意时刻只能被⼀个进程访问,信号量就实现了这⼀保护机制。
- 信号量其实是⼀个整型的计数器,主要用于实现进程间的互斥与同步,不是用于缓存进程间通信的数据。
⑤信号:
信号是进程间通信机制中唯⼀的异步通信机制。
对于异常情况下的工作模式,就需要用信号的方式来通知进程。
Ctrl+C 产⽣ SIGINT 信号,表示终止该进程; Ctrl+Z 产⽣ SIGTSTP 信号,表示停止该进程,但还未结束;
1.执行默认操作。Linux 对每种信号都规定了默认操作,例如,SIGTERM 信号,就是终止进程的意思。
2.捕捉信号。我们可以为信号定义⼀个信号处理函数。当信号发⽣时,我们就执⾏相应的信号处理函数。
3.忽略信号。当我们不希望处理某些信号的时候,就可以忽略该信号,不做任何处理。有两个信号是应⽤进程⽆法捕捉和忽略的,即 SIGKILL 和 SEGSTOP ,它们⽤于在任何时候中断或结束某⼀进程。
⑥Socket:
那要想跨网络与不同主机上的进程之间通信,就需要 Socket 通信了。还可以在同主机上进程间通信。
int socket(int domain, int type, int protocal) 根据Socket类型:
实现 TCP 字节流通信: socket 类型是 AF_INET 和 SOCK_STREAM;
实现 UDP 数据报通信:socket 类型是 AF_INET 和 SOCK_DGRAM;
2、线程间通信:
线程间的通信目的主要是用于线程同步。所以线程没有像进程通信中的用于数据交换的通信机制。
同一进程的不同线程共享同一份内存区域,所以线程之间可以方便、快速地共享信息。只需要将数据复制到共享(全局或堆)变量中即可。但是需要避免出现多个线程试图同时修改同一份信息。
1、互斥锁
在访问共享资源前进行加锁,在访问完成后释放互斥锁。加锁后其他想访问此资源的线程会进入阻塞,直到当前线程释放互斥锁。注意防止死锁。
2、读写锁
一次只有一个线程可以占有写模式的读写锁,但是多个线程可以同时占有读模式的读写锁。
- 当读写锁是写加锁状态时,在这个锁被解锁之前,所有试图对这个锁加锁的线程都会被阻塞。
- 当读写锁在读加锁状态时,所有试图以读模式对它进行加锁的线程都可以得到访问权,但是任何希望以写模式对此锁进行加锁的线程都会阻塞,直到所有的线程释放它们的读锁为止。
3、条件变量
互斥量用于上锁,条件变量则用于等待,并且条件变量总是需要与互斥锁一起使用,运行线程以无竞争的方式等待特定的条件发生。
条件变量本身是由互斥量保护的,线程在改变条件变量之前必须首先加互斥锁。(某共享数据达到某值的时候,唤醒等待这个共享数据的线程)
4、信号量
使用线程的信号量可以高效地完成基于线程的资源计数。信号量实际上是一个非负的整数计数器,用来实现对公共资源的控制。
在公共资源增加的时候,信号量就增加;公共资源减少的时候,信号量就减少;只有当信号量的值大于0的时候,才能访问信号量所代表的公共资源。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/12186.html