1. 程式人生 > >人工智慧(PythonNet)—— 程序間通訊(管道、訊息佇列、共享記憶體、訊號、訊號量、套接字)

人工智慧(PythonNet)—— 程序間通訊(管道、訊息佇列、共享記憶體、訊號、訊號量、套接字)

一、程序間通訊

        程序間通訊(IPC,InterProcess Communication)是指在不同程序之間傳播或交換資訊。

        由於每個程序的空間是互相獨立的,程序之間無法互相直接獲取彼此的資源,故引入程序間通訊來實現程序間的資源互動。

        程序間通訊方法:管道、訊息佇列、共享記憶體、訊號、訊號量、套接字。

        補充:檔案型別(檢視方法:ls -l 或 ll)
                b(塊裝置檔案)
                c(字元裝置檔案)
                d(資料夾)   
                - (普通檔案)
                l (連結檔案)    link
                s  套接字檔案
                p  管道檔案


二、管道通訊   Pipe

        在記憶體中開闢一段空間,形成管道結構,管道對多個程序可見,程序可以對管道進行讀寫操作,實現多程序之間的通訊。

        from multiprocess import Pipe  # 匯入庫

1、Pipe函式

        fd1,fd2 = Pipe(duplex = True)
        功能:建立一個管道
        引數:預設為雙向管道
                    如果設定為False,則為單向管道
        返回值:返回兩個管道流物件,表示管道的兩端
                      如果雙向管道,fd1 fd2都可以進行讀寫操作
                      如果是單向管道,則fd1只可讀,fd2只可寫

        fd.recv()
        功能:從管道讀取內容(接收訊息)
        引數:無
        返回值:讀到的內容(接收訊息)
                說明:如果管道無內容則阻塞

        fd.send(data)
        功能: 向管道寫入內容(傳送訊息)
        引數: 要傳送的內容
                說明:如果沒有接收端則管道破裂

2、示例

from multiprocessing import Process,Pipe 
import os,time 

#如果引數為False則fd1只能recv  fd2只能send
# fd1,fd2 = Pipe(False)

#建立一個雙向管道
fd1,fd2 = Pipe()
# fd1.close()

def fun(name):
    time.sleep(3)
    #發字串到管道
    fd2.send("hello " + str(name))
    print(os.getppid(),"----",os.getpid())

jobs = []
for i in range(5):
    p = Process(target = fun,args = (i,))
    jobs.append(p)
    p.start() 

#接收子程序傳送的訊息
for i in range(5):
    data = fd1.recv()
    print(data) 

for i in jobs:
    i.join()

三、訊息佇列 Queue

        佇列存取規則: 先進先出

        在記憶體中開闢佇列結構空間,多個程序可以向佇列投放訊息,在取出的時候按照存入順序取出;任何擁有佇列的程序都可以存取訊息

1、Queue函式

        建立佇列
        q = Queue(maxsize = 0)
        功能 : 建立佇列
        引數 : maxsize  預設為0,表示根據系統分配空間儲存訊息
                                   如果傳入一個正整數,表示最多存放多少條訊息
        返回 : 訊息佇列物件

        q.put(data, [block, timeout])
        功能: 存放訊息
        引數: data        存入的訊息 (python資料型別)
                   block       預設為True表示當佇列滿的時候阻塞
                                   設定為False則表示非阻塞
                   timeout   當block為True表示超時時間

        data = q.get([block, timeout])
        功能 : 取出訊息
        引數 : block     預設為True 當佇列空時阻塞
                                  設定為False表示非阻塞
                    timeout  當block為True時表示超時時間
        返回值 : 返回獲取的訊息

        q.full()   判斷佇列是否為滿
        q.empty()  判斷佇列是否為空
        q.qsize()  判斷當前佇列有多少訊息
        q.close()  關閉佇列

2、示例

        a、函式
from  multiprocessing import Queue 
from time import sleep
#建立佇列
q = Queue(3) 

q.put(1)
print(q.full())
q.put(2)
q.put(3)
print(q.full())

# 設定超時事件為3sec
# q.put(4,True,3)

print(q.get())
print("佇列中還有%d條訊息"%q.qsize())
print(q.empty())
q.close() #關閉佇列
        b、管道收發
from multiprocessing import Process,Queue 
import time 

#建立訊息佇列
q = Queue()

def fun1():
    time.sleep(1)
    q.put("我是程序1")

def fun2():
    time.sleep(2)
    print("取訊息:",q.get())

p1 = Process(target = fun1)
p2 = Process(target = fun2)
p1.start()
p2.start()

p1.join()
p2.join()

四、共享記憶體

        在記憶體中開闢一段空間,儲存資料,對多個程序可見。每次寫入共享記憶體中的資料會覆蓋之前的內容。由於對記憶體格式化較少,所以存取速度快。

        from multiprocessing import Value,Array

1、函式

        obj = Value(ctype,obj)
        功能:開闢共享記憶體空間
        引數:ctype   字串  要轉變的c的資料型別(對照ctype表)
                    obj   共享記憶體的初始化資料
        返回:返回一個共享記憶體物件
                補充:obj.value  表示共享記憶體中的值。對其修改或者使用即可

        obj = Array(ctype,obj)
        功能: 開闢共享記憶體
        引數: ctype    要轉化的c的型別
                   obj        列表,表示要存入的資料,要求列表中數型別一致
                                正整數,表示開闢一個多大的序列空間
        返回值:返回一個共享記憶體物件
                補充:正常運算元值,讀取和賦值

2、資料型別(ctype對照表)

Type codeC TypePython TypeMinimum size in bytesNotes
'b'signed charint1
'B'unsigned charint1
'u'Py_UNICODEUnicode character2(1)
'h'signed shortint2
'H'unsigned shortint2
'i'signed intint2
'I'unsigned intint2
'l'signed longint4
'L'unsigned longint4
'q'signed long longint8(2)
'Q'unsigned long longint8(2)
'f'floatfloat4
'd'doublefloat8
        參考來源:https://docs.python.org/3.6/library/array.html

3、示例

        a、共享記憶體 —— value
from multiprocessing import Value,Process 
import time 
import random 

#向共享記憶體存錢
def deposite(money):
    for i in range(100):
        time.sleep(0.03)
        money.value += random.randint(1,200)
#從共享記憶體取錢
def withdraw(money):
    for i in range(100):
        time.sleep(0.02)
        money.value -= random.randint(1,150)

#建立共享記憶體物件
money = Value('i',2000)

d = Process(target = deposite,args = (money,))
w = Process(target = withdraw,args = (money,))
d.start()
w.start()
d.join()
w.join()

#檢視共享記憶體資料
print(money.value)
        b、共享記憶體 —— array
from multiprocessing import Array,Process 
import time 

def fun(shm):
    for i in shm:
        print(i)
    shm[2] = 1000

#開闢共享記憶體空間,可容納6個整數
#初始值是[1,2,3,4,5,6]
# shm = Array('i',[1,2,3,4,5,6])
#表示在共享記憶體中開闢一個包含6個整形的空間
shm = Array('i',6)

p = Process(target = fun,args = (shm,))
p.start()
p.join()
for i in shm:
    print(i)






八、附錄:目錄


相關推薦

人工智慧PythonNet—— 程序通訊管道訊息佇列共享記憶體訊號訊號

一、程序間通訊        程序間通訊(IPC,InterProcess Communication)是指在不同程序之間傳播或交換資訊。        由於每個程序的空間是互相獨立的,程序之間無法互相直接獲取彼此的資源,故引入程序間通訊來實現程序間的資源互動。       

linux (五程序通訊匿名管道,命名管道訊息佇列

程序間通訊 程序間通訊的目的 資料傳輸:一個程序需要將他的資料傳送給另一個程序 資源共享:多個程序之間共享同樣的資源 通知事件:一個程序需要向另一個或一組程序傳送訊息,通知它發生了某種事件(如程序終止時要通知父程序) 程序控制:有寫程序希望完全控制另一

Linux 程序通訊共享記憶體

上篇部落格我們講了,匿名管道,命名管道,訊息佇列,並使用了他們,初步瞭解了程序間通訊的概念。下面我們要說共享記憶體。 共享記憶體函式 shmget函式 功能:用來建立共享記憶體 原型 int shmget(key_t key,size_t si

ython實現程序通訊有Queue,Pipe,Value+Array等,其中Queue實現多個程序通訊,而Pipe實現兩個程序通訊,而Value+Array使用得是共享記憶體對映檔案的方式,所以速度比較快

1.Queue的使用 from multiprocessing import Queue,Process import os,time,random #新增資料函式 def proc_write(queue,urls): print("程序(%s)正在寫入..."%(os.getpid()))

程序通訊——管道訊息佇列共享記憶體

程序間通訊的本質是讓兩個不相干的程序看到同一份資源。這個資源是由作業系統提供的一個檔案。程序間通訊的目的:1.資料傳輸:一個程序需要將它 的資料傳送給另一個程序。2.資源共享:多個程序之間共享同樣的資源。3.通知事件:一個程序需要向另一個(組)程序傳送訊息,通知它們發生了

Linux程序通訊IPC方式總結

程序間通訊概述 程序通訊的目的 資料傳輸  一個程序需要將它的資料傳送給另一個程序,傳送的資料量在一個位元組到幾M位元組之間 共享資料  多個程序想要操作共享資料,一個程序對共享資料 通知事件 一個程序需要向另一個或一組程序傳送訊息,通知它(它們)

程序通訊命名管道fifo

要學習命名管道,我們必須首先對管道的特性有一定的瞭解,管道特性以及匿名管道連結 命名管道:管道的一個限制就是隻能用在親緣程序之間,如果我們想在不相關的程序間進行資料交換,可以使用FIFO檔案來進行,它叫做命名管道。 命名管道:檔案系統可見,是一個特殊型別(管道型別)的檔案。命名管

程序通訊共享記憶體

概念: 共享記憶體區是最快的IPC形式。⼀一旦這樣的記憶體對映到共享它的程序的地址空間,這些程序間資料傳遞不再 涉及到核心,換句話說是程序不再通過執⾏行進⼊入核心的系統調⽤用來傳遞彼此的資料。 共享記憶體中的函式: shmget函式: 功能:⽤用來建立共享記憶體 原型

Linux:程序通訊匿名管道命名管道共享記憶體訊息佇列訊號

目錄 程序間通訊的介紹 管道 匿名管道 原理: 程式碼實現 匿名管道特性 實現管道符 |  命名管道 命名管道特性 程式碼實現 管道讀寫規則 作業系統中ipc的相關命令 共享記憶體(重點) 生命週期: 程式碼實現 程式碼實現獲

Android IPC程序通訊 Binder連線池

Binder管家之Binder連線池 IPC程序間通訊(四)之AIDL中的AIDL由一個Service進行管理,若是建立10個AIDL業務模組是不是也要建立10個Service來進行管理,那100個呢?顯然繁瑣,怎麼辦麼,用Binder連線池呀! 工作機制: 1.每個業務模組建立其AID

Android IPC程序通訊Socket

網路通訊之Socket 特點:功能強大,可通過網路傳輸位元組流,支援一對多併發即時通訊。 不支援RPC。 服務端實現: public class SorviceSocket extends Service { private static final String TAG

Androi IPC程序通訊ContentProvider

程序間通訊之ContentProvider 一,介紹 1.底層實現也是Binder 2.其6個方法除了onCreate方法運行於主執行緒,其他4個方法由外界回撥並運行於Binder執行緒池。 3.註冊ContentProvider需要一個屬性android:authorities=“XX

Android IPC程序通訊AIDL

AIDL-Android介面定義語言 一· 1.相比於Messenger AIDL可跨程序呼叫方法。 2.支援資料型別: (1) Java 的原生基本型別(int, long, char, boolean, double等) (2)String 和CharSequence (3) Arr

Android IPC程序通訊Binder

程序間通訊的介質Binder Binder實現了IBinder介面,是android中跨程序通訊的一種方式。是服務端和客戶端通訊的媒介。 Binder的建立: 1.建立自定義類Book.java實現Parcelable介面,以實現序列化可反序列化。 public class Book

Android IPC程序通訊Messenger

Messenger實現程序間低併發即時通訊 Messenger是一種輕量級的IPC,底層實現是AIDL,即可認為Binder。通過在Message中攜帶Bundle進而實現程序之間傳遞資料。由於Messenger一次只能處理一個請求,因此服務端們不用考慮執行緒同步問題。 一,我們在服務端

Android IPC程序通訊檔案共享

IPC程序間通訊簡介 1.在AndroidManifest.xml中宣告元件android:process屬性。 不指定process屬性,則預設執行在主程序中,主程序名字為包名。 android:process = package:remote,將執行在package:remote程序

Linux 程序通訊訊號

1 訊號量概述 訊號量和其他IPC不同,並沒有在程序之間傳送資料,訊號量用於多程序在存取共享資源時的同步控制就像交通路口的紅路燈一樣,當訊號量大於0,表示綠燈允許通過,當訊號量等於0,表示紅燈,必須停下來等待綠燈才能通過。 程序間的互斥關係與同步關係存在的根源在於臨界資

Linux 程序通訊IPC的特性

1.識別符號和鍵 每個核心中的IPC結構(訊息佇列、訊號量或共享儲存段)都用一個非負整數的識別符號 (identifier)加以引用。 例如,要向一個訊息佇列傳送訊息或者從一個訊息佇列取訊息,只需要知道其佇列識別符號。 當一個IPC結構被建立,然後又被刪除時,與這種結構

Linux 程序通訊共享記憶體

可以說, 共享記憶體是一種最為高效的程序間通訊方式, 因為程序可以直接讀寫記憶體, 不需要任何資料的複製。 為了在多個程序間交換資訊, 核心專門留出了一塊記憶體區, 這段記憶體區可以由需要訪問的程序將其對映到自己的私有地址空間。 因此, 程序就可以直接讀寫這一記憶體區而不需要

linux程序通訊IPC小結

linux IPC型別 1、匿名管道 2、命名管道 3、訊號 4、訊息佇列 5、共享記憶體 6、訊號量 7、Socket 1、匿名管道 過程: 1、管道實質是一個核心緩衝區,先進先出(佇列)讀取緩衝區記憶體資料 2、一個數據只能讀一次,讀完後在緩衝區就不存在