LinuxIPC通信之匿名管道(C+Python實現)

進程通信是指在進程間傳輸數據(交換信息)。進程通信根據交換信息量的多少和效率的高低,分爲低級通信(只能傳遞狀態和整數值)和高級通信(提高信號通信的效率,傳遞大量數據,減輕程序編制的複雜度)。其中高級進程通信分爲三種方式:共享內存模式、消息傳遞模式、共享文件模式。

在別人博客看到的這段話,也不知道那個抄那個的哈哈

linux下的進程通信手段基本上是從Unix平臺上的進程通信手段繼承而來的。而對Unix發展做出重大貢獻的兩大主力AT&T的貝爾實驗室及BSD(加州大學伯克利分校的伯克利軟件發佈中心)在進程間通信方面的側重點有所不同。前者對Unix早期的進程間通信手段進行了系統的改進和擴充,形成了“system V IPC”,通信進程侷限在單個計算機內;後者則跳過了該限制,形成了基於套接口(socket)的進程間通信機制。

常見的通信方式:

1. 管道pipe:管道是一種半雙工的通信方式,數據只能單向流動,而且只能在具有親緣關係的進程間使用。進程的親緣關係通常是指父子進程關係。
2. 命名管道FIFO:有名管道也是半雙工的通信方式,但是它允許無親緣關係進程間的通信。

3. 信號 ( sinal ) : 信號是一種比較複雜的通信方式,用於通知接收進程某個事件已經發生。
4. 消息隊列MessageQueue:消息隊列是由消息的鏈表,存放在內核中並由消息隊列標識符標識。消息隊列克服了信號傳遞信息少、管道只能承載無格式字節流以及緩衝區大小受限等缺點。
5. 共享存儲SharedMemory:共享內存就是映射一段能被其他進程所訪問的內存,這段共享內存由一個進程創建,但多個進程都可以訪問。共享內存是最快的 IPC 方式,它是針對其他進程間通信方式運行效率低而專門設計的。它往往與其他通信機制,如信號,配合使用,來實現進程間的同步和通信。
6. 信號量Semaphore:信號量是一個計數器,可以用來控制多個進程對共享資源的訪問。它常作爲一種鎖機制,防止某進程正在訪問共享資源時,其他進程也訪問該資源。因此,主要作爲進程間以及同一進程內不同線程之間的同步手段。
7. 套接字Socket:套解口也是一種進程間通信機制,與其他通信機制不同的是,它可用於不同及其間的進程通信。

第一篇首先來實現pipe通信

匿名管道:

  • 只能用於具有血緣關係的進程之間通信
  • 生命週期隨進程,進程退出,管道釋放
  • 管道是半雙工的,數據只能從一個方向傳輸
  • 管道是基於字節流的
  • 管道是自帶同步機制的,在保證數據安全的前提下,按照特定順序訪問臨界資源

python:

函數說明:

multiprocessing.Pipe([duplex]) 返回2個連接對象(conn1, conn2),代表管道的兩端,默認是雙向通信.

如果duplex=False,conn1只能用來接收消息,conn2只能用來發送消息.不同於os.open之處在於os.pipe()返回2個文件描述符(r, w),表示可讀的和可寫的

多進程 Multiprocessing 模塊

Process 類
Process 類用來描述一個進程對象。創建子進程的時候,只需要傳入一個執行函數和函數的參數即可完成 Process 示例的創建。

star() 方法啓動進程,
join() 方法實現進程間的同步,等待所有進程退出。
close() 用來阻止多餘的進程涌入進程池 Pool 造成進程阻塞。
multiprocessing.Process(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
target 是函數名字,需要調用的函數
args 函數需要的參數,以 tuple 的形式傳入

#!/usr/bin/python3
import multiprocessing

arron_say=('1','3','5','7','9')
kobe_say=('2','4','6','8','10')

def arron_handler(read_fd,write_fd):
    for str in kobe_say:
        print("kobe say:>%s"%read_fd.recv())
        write_fd.send(str)

def kobe_handler(read_fd,write_fd):
    for str in arron_say:
        write_fd.send(str)
        print("arron say:>%s"%read_fd.recv())

(read_fd1,write_fd1) = multiprocessing.Pipe()
(read_fd2,write_fd2) = multiprocessing.Pipe()

arron = multiprocessing.Process(target=arron_handler,args=(read_fd1,write_fd2))

arron.start()
kobe_handler(read_fd2,write_fd1)
#arron.start()
read_fd1.close()
read_fd2.close()
write_fd1.close()
write_fd2.close()

arron.join()

C:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

int main(int argc, char **argv)
{
	int fd[2];

	if(pipe(fd) == -1)
	{
		perror("pipe()");
		exit(1);
	}

	pid_t x = fork();

	if(x == 0)
	{
		char *s = "hello, I am your child\n";
		write(fd[1], s, strlen(s));
	}
	
	if(x > 0)
	{
		char buf[30];
		bzero(buf, 30);

		read(fd[0], buf, 30);
		printf("from child: %s", buf);
	}

	close(fd[0]);
	close(fd[1]);
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章