Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Apakah kaedah komunikasi antara proses Python?

Apakah kaedah komunikasi antara proses Python?

PHPz
PHPzke hadapan
2023-06-03 14:09:071804semak imbas

Apakah komunikasi proses

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.

Penciptaan baris gilir - berbilang pemprosesan

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.

Kaedah untuk komunikasi antara proses

函数名 介绍 参数 返回值
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.

Komunikasi antara proses - kes demonstrasi baris gilir

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:

Apakah kaedah komunikasi antara proses Python?

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:

Apakah kaedah komunikasi antara proses Python?

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:

Apakah kaedah komunikasi antara proses Python?

Tambah data pada fungsi hantar dalam kelompok

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:

Apakah kaedah komunikasi antara proses Python?

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.

Bahagian

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.

Cara komunikasi antara proses lain - Tambahan

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 penyegerakan

Fungsi: Melindungi sumber kritikal

4 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!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam