Berikut adalah contoh mekanisme komunikasi: Kita semua biasa dengan perkataan komunikasi, contohnya, seseorang ingin menghubungi teman wanitanya. Setelah panggilan dibuat, baris gilir tersirat (perhatikan istilah ini) terbentuk. Pada masa ini, orang ini akan terus memberitahu maklumat teman wanitanya melalui dialog, dan teman wanita orang ini turut mendengar. Saya fikir dalam kebanyakan kes ia mungkin sebaliknya.
Kedua-duanya boleh dibandingkan dengan dua proses Proses "orang ini" perlu menghantar maklumat kepada proses "teman wanita", jadi ia memerlukan bantuan barisan. Memandangkan teman wanita perlu menerima maklumat dalam baris gilir pada setiap masa, dia boleh melakukan perkara lain pada masa yang sama, yang bermaksud bahawa komunikasi antara kedua-dua proses bergantung terutamanya pada baris gilir.
Baris gilir ini boleh menyokong penghantaran dan penerimaan mesej "Orang ini" bertanggungjawab untuk menghantar mesej, manakala "teman wanita" bertanggungjawab untuk menerima mesej.
Memandangkan baris gilir menjadi tumpuan, mari kita lihat cara membuat baris gilir.
masih menggunakan modul berbilang pemprosesan dan memanggil fungsi Gilir modul ini untuk mencipta baris gilir.
函数名 | 介绍 | 参数 | 返回值 |
---|---|---|---|
Queue | 队列的创建 | mac_count | 队列对象 |
Pengenalan fungsi baris gilir: Call Queue untuk membuat baris gilir; ia mempunyai parameter mac_count yang mewakili jumlah maksimum maklumat yang boleh dibuat dalam baris gilir Jika tidak lulus, panjang lalai adalah tidak terhad . Selepas menghidupkan objek baris gilir, anda perlu mengendalikan objek baris gilir untuk memasukkan dan mengeluarkan data.
函数名 | 介绍 | 参数 | 返回值 |
---|---|---|---|
put | 将消息放入队列 | message | 无 |
get | 获取队列消息 | 无 | str |
Pengenalan fungsi letak: masukkan data. Ia mempunyai satu mesej parameter, iaitu jenis rentetan.
dapatkan pengenalan fungsi: digunakan untuk menerima data dalam baris gilir. (Sebenarnya, ini adalah senario json biasa. Banyak penghantaran data dalam rentetan. Sisipan dan pengambilan baris gilir menggunakan rentetan, jadi json sangat sesuai untuk senario ini.)
Langkah seterusnya ialah Mari berlatih menggunakan barisan.
Contoh kod adalah seperti berikut:
# coding:utf-8 import json import multiprocessing class Work(object): # 定义一个 Work 类 def __init__(self, queue): # 构造函数传入一个 '队列对象' --> queue self.queue = queue def send(self, message): # 定义一个 send(发送) 函数,传入 message # [这里有个隐藏的bug,就是只判断了传入的是否字符串类型;如果传入的是函数、类、集合等依然会报错] if not isinstance(message, str): # 判断传入的 message 是否为字符串,若不是,则进行 json 序列化 message = json.dumps(message) self.queue.put(message) # 利用 queue 的队列实例化对象将 message 发送出去 def receive(self): # 定义一个 receive(接收) 函数,不需传入参数,但是因为接收是一个源源不断的过程,所以需要使用 while 循环 while 1: result = self.queue.get() # 获取 '队列对象' --> queue 传入的message # 由于我们接收的 message 可能不是一个字符串,所以要进程异常的捕获 try: # 如果传入的 message 符合 JSON 格式将赋值给 res ;若不符合,则直接使用 result 赋值 res res = json.loads(result) except: res = result print('接收到的信息为:{}'.format(res)) if __name__ == '__main__': queue = multiprocessing.Queue() work = Work(queue) send = multiprocessing.Process(target=work.send, args=({'message': '这是一条测试的消息'},)) receive = multiprocessing.Process(target=work.receive) send.start() receive.start()
Pengecualian yang dihadapi apabila menggunakan baris gilir untuk mewujudkan komunikasi antara proses
Tetapi di sini akan Mesej ralat muncul, seperti yang ditunjukkan di bawah:
Contoh tangkapan skrin mesej ralat adalah seperti berikut:
Mesej ralat di sini bermakna fail itu belum ditemui. Malah, apabila kita menggunakan baris gilir untuk melakukan put() dan get(), kunci halimunan ditambah, iaitu .SemLock dalam bulatan dalam gambar di atas. Kami tidak perlu mengambil berat tentang punca khusus ralat ini Menyelesaikan masalah ini sebenarnya sangat mudah.
FileNotFoundError: [Errno 2] Tiada fail atau direktori seperti itu Resolusi Pengecualian
Yang perlu menyekat proses hanyalah satu daripada sub-proses hantar atau terima. Hanya sekat satu daripadanya adalah teori. Tetapi subproses terima kami ialah gelung sementara, yang akan sentiasa dilaksanakan, jadi kami hanya perlu menambah gabungan pada subproses hantar.
Rajah penyelesaian adalah seperti berikut:
PS: Walaupun masalah ralat telah diselesaikan, program tidak keluar seperti biasa.
Malah, memandangkan proses terima kami adalah gelung sementara, kami tidak tahu bila ia akan diproses dan tiada cara untuk menamatkannya serta-merta. Jadi kita perlu menggunakan fungsi terminate() dalam proses terima untuk menamatkan hujung penerima.
Keputusan yang dijalankan adalah seperti berikut:
Buat fungsi baharu dan tulis untuk gelung untuk mensimulasikan penambahan batch untuk dihantar mesej
dan kemudian tambahkan urutan pada fungsi ini yang mensimulasikan penghantaran data dalam kelompok.
Kod sampel adalah seperti berikut:
# coding:utf-8 import json import time import multiprocessing class Work(object): # 定义一个 Work 类 def __init__(self, queue): # 构造函数传入一个 '队列对象' --> queue self.queue = queue def send(self, message): # 定义一个 send(发送) 函数,传入 message # [这里有个隐藏的bug,就是只判断了传入的是否字符串类型;如果传入的是函数、类、集合等依然会报错] if not isinstance(message, str): # 判断传入的 message 是否为字符串,若不是,则进行 json 序列化 message = json.dumps(message) self.queue.put(message) # 利用 queue 的队列实例化对象将 message 发送出去 def send_all(self): # 定义一个 send_all(发送)函数,然后通过for循环模拟批量发送的 message for i in range(20): self.queue.put('第 {} 次循环,发送的消息为:{}'.format(i, i)) time.sleep(1) def receive(self): # 定义一个 receive(接收) 函数,不需传入参数,但是因为接收是一个源源不断的过程,所以需要使用 while 循环 while 1: result = self.queue.get() # 获取 '队列对象' --> queue 传入的message # 由于我们接收的 message 可能不是一个字符串,所以要进程异常的捕获 try: # 如果传入的 message 符合 JSON 格式将赋值给 res ;若不符合,则直接使用 result 赋值 res res = json.loads(result) except: res = result print('接收到的信息为:{}'.format(res)) if __name__ == '__main__': queue = multiprocessing.Queue() work = Work(queue) send = multiprocessing.Process(target=work.send, args=({'message': '这是一条测试的消息'},)) receive = multiprocessing.Process(target=work.receive) send_all = multiprocessing.Process(target=work.send_all,) send_all.start() # 这里因为 send 只执行了1次,然后就结束了。而 send_all 却要循环20次,它的执行时间是最长的,信息也是发送的最多的 send.start() receive.start() # send.join() # 使用 send 的阻塞会造成 send_all 循环还未结束 ,receive.terminate() 函数接收端就会终结。 send_all.join() # 所以我们只需要阻塞最长使用率的进程就可以了 receive.terminate()
Keputusan yang dijalankan adalah seperti berikut:
Daripada rajah di atas kita boleh lihat dua proses menghantar dan menghantar_semua Mesej boleh dihantar melalui objek Baris gilir instantiated Fungsi terima yang sama juga akan mencetak mesej yang dihantar oleh kedua-dua proses.
Dalam bab ini, kami berjaya menggunakan baris gilir untuk mencapai komunikasi silang proses, dan juga menguasai kemahiran operasi baris gilir. Dalam baris gilir, satu hujung (di sini kami menunjukkan hujung hantar) menambah maklumat yang berkaitan melalui kaedah put, dan hujung yang satu lagi menggunakan kaedah get untuk mendapatkan maklumat yang berkaitan bekerjasama antara satu sama lain untuk mencapai kesan satu proses komunikasi.
Selain baris gilir, proses juga boleh berkomunikasi menggunakan paip, semaphore, dan ingatan yang dikongsi Jika anda berminat, anda boleh mempelajari kaedah ini. Anda boleh mengembangkannya sendiri.
Python menyediakan pelbagai cara untuk komunikasi proses, termasuk isyarat, paip, baris gilir mesej, semafor, memori kongsi, soket, dll.
Terdapat dua kaedah utama: Queue dan Pipe digunakan untuk melaksanakan komunikasi antara pelbagai proses, dan Pipe ialah komunikasi antara dua proses.
1. Paip: dibahagikan kepada paip tanpa nama dan paip dinamakan
Paip tanpa nama: memohon penimbal bersaiz tetap dalam kernel Secara amnya, fock digunakan Fungsi melaksanakan komunikasi antara proses ibu bapa dan anak
Paip bernama: Memohon penimbal saiz tetap dalam ingatan Program ini mempunyai hak untuk menulis dan membaca Proses yang tidak berkaitan dengan darah juga boleh berkomunikasi antara proses
Ciri-ciri: Berorientasikan kepada aliran bait mengikut kernel; >Satu cara untuk menulis semula ialah: sedang beroperasi Satu baris gilir diwujudkan dalam kernel sistem, yang mengandungi berbilang elemen datagram Pelbagai proses boleh mengakses baris gilir melalui pemegang tertentu. Baris gilir mesej boleh digunakan untuk menghantar data dari satu proses ke proses yang lain. Setiap blok data dianggap mempunyai jenis, dan blok data yang diterima oleh proses penerima boleh mempunyai jenis yang berbeza. Baris gilir mesej juga mempunyai kekurangan yang sama seperti paip, iaitu, terdapat had atas pada panjang maksimum setiap mesej, terdapat had atas pada jumlah bilangan bait dalam setiap baris gilir mesej, dan terdapat juga had atas pada jumlah bilangan baris gilir mesej pada sistem
Ciri: Baris gilir mesej boleh dianggap sebagai senarai terpaut global Nod senarai terpaut menyimpan jenis dan kandungan datagram dan ditandakan dengan pengecam mesej baris gilir; baris gilir mesej membenarkan satu atau lebih proses untuk menulis atau membaca mesej;
3. Semaphore: Buat koleksi semaphore (pada asasnya tatasusunan) dalam kernel Elemen tatasusunan (semaphore) semuanya 1. Gunakan operasi P untuk melaksanakan -1, dan gunakan operasi V untuk +1<.>
P(sv): Jika nilai sv lebih besar daripada sifar, kurangkan ia sebanyak 1; jika nilainya ialah sifar, tangguhkan pelaksanaan program V(sv): Jika terdapat adalah sebab proses lain Jika ia digantung sementara menunggu sv, biarkan ia meneruskan berjalan Jika tiada proses digantung sementara menunggu sv, tambahkan 1 padanya Operasi PV digunakan untuk proses yang sama untuk mencapai pengecualian bersama. ; Operasi PV digunakan untuk Proses yang berbeza merealisasikan penyegerakanFungsi: Melindungi sumber kritikal4 Memori yang dikongsi: Petakan bahagian memori fizikal yang sama ke ruang alamat maya proses yang berbeza untuk mencapai antara -proses komunikasi Perkongsian sumber yang sama. Apabila bercakap tentang kaedah komunikasi antara proses, memori kongsi boleh dikatakan sebagai bentuk IPC yang paling berguna dan terpantas Ciri-ciri: Berbeza daripada menukar dan menyalin data yang kerap daripada mod pengguna ke mod kernel, membaca terus daripada ingatan Tidak mengapa; ingatan yang dikongsi ialah sumber yang kritikal, jadi atomicity mesti dijamin apabila operasi diperlukan. Anda boleh menggunakan semaphore atau mutex.Atas ialah kandungan terperinci Apakah kaedah komunikasi antara proses Python?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!