Ketahui lebih lanjut tentang kumpulan proses Python dan kunci proses

WBOY
Lepaskan: 2022-05-10 21:18:52
ke hadapan
2661 orang telah melayarinya

Artikel ini membawa anda pengetahuan yang berkaitan tentang python, yang terutamanya memperkenalkan isu yang berkaitan dengan kumpulan proses dan kunci proses, termasuk modul penciptaan kumpulan proses, fungsi kumpulan proses, dll. , mari kita lihat bersama-sama , saya harap ia akan membantu semua orang.

Ketahui lebih lanjut tentang kumpulan proses Python dan kunci proses

Pembelajaran yang disyorkan: tutorial video python

Kolam Proses

Apakah itu kolam proses

Kami menyebut isu tentang proses dalam bab sebelumnya Jika terlalu banyak proses dibuat, sumber akan digunakan terlalu banyak. Untuk mengelakkan keadaan ini, kita perlu menetapkan bilangan proses, dan pada masa ini kita memerlukan bantuan kumpulan proses.

Kita boleh menganggap kumpulan proses sebagai kumpulan di mana sejumlah proses tertentu dibuat terlebih dahulu. Lihat gambar di bawah:


Ketahui lebih lanjut tentang kumpulan proses Python dan kunci proses


Sebagai contoh, tatasusunan segi empat tepat merah ini mewakili kumpulan proses dan terdapat 6 proses dalam kumpulan ini. 6 proses ini akan dibuat bersama-sama dengan kumpulan proses Bukan itu sahaja, kami pernah berkata apabila mempelajari kitaran hayat berorientasikan objek bahawa setiap objek yang instantiated akan dikitar semula oleh pengurus memori selepas digunakan.

Proses kami juga akan dikitar semula oleh pengurus memori bersama-sama dengan proses penciptaan dan penutupan Ini adalah benar untuk setiap proses Proses yang dibuat apabila proses ditutup juga akan menggunakan jumlah prestasi tertentu. Proses dalam kumpulan proses tidak akan ditutup selepas ia dicipta, dan boleh digunakan semula sepanjang masa, dengan itu mengelakkan penggunaan sumber penciptaan dan penutupan, dan mengelakkan operasi berulang penciptaan dan penutupan, yang meningkatkan kecekapan.

Sudah tentu, apabila kita selesai melaksanakan program dan menutup kumpulan proses, proses itu juga akan ditutup.

Apabila kami mempunyai tugasan yang perlu dilaksanakan, kami akan menentukan sama ada terdapat sebarang proses terbiar dalam kumpulan proses semasa (yang dipanggil proses terbiar sebenarnya adalah proses dalam kumpulan proses yang tidak melaksanakan tugasan ). Apabila proses melahu, tugas akan mencari proses untuk melaksanakan tugas. Jika semua proses dalam kumpulan proses semasa berada dalam keadaan tidak melahu, tugasan akan memasuki keadaan menunggu Ia tidak akan masuk atau keluar dari kumpulan proses sehingga proses dalam kumpulan proses melahu untuk melaksanakan tugas.

Ini ialah peranan kumpulan proses.

Modul penciptaan kumpulan proses - pemproses berbilang

Buat fungsi kumpulan proses - Kolam

函数名 介绍 参数 返回值
Pool 进程池的创建 Processcount 进程池对象

Pool功能介绍:通过调用 "multiprocessing" 模块的 "Pool" 函数来帮助我们创建 "进程池对象" ,它有一个参数 "Processcount" (一个整数),代表我们这个进程池中创建几个进程。

Kaedah biasa kumpulan proses

Selepas mencipta objek kumpulan proses, kita perlu mengendalikan prosesnya Mari kita lihat apakah kaedah (fungsi) biasa yang ada. .

函数名 介绍 参数 返回值
apply_async 任务加入进程池(异步) func,args
close 关闭进程池
join 等待进程池任务结束
  • fungsi apply_async: Fungsinya adalah untuk menambah tugasan pada kumpulan proses dan dilaksanakan secara tak segerak. 异步 Kami belum mempelajari pengetahuan ini lagi, jadi jangan risau tentang maksudnya lagi. Ia mempunyai dua parameter: func 与 agrs, func ialah fungsi yang ditambahkan pada kumpulan proses; args ialah tuple, mewakili parameter fungsi, yang betul-betul sama seperti semasa kita mencipta dan menggunakan proses.
  • fungsi tutup: Selepas kita selesai menggunakan kumpulan proses, kita boleh menutup kumpulan proses dengan memanggil fungsi tutup. Ia tidak mempunyai parameter dan tiada nilai pulangan.
  • Fungsi Sertai: Ia selaras dengan fungsi gabungan yang kami pelajari dalam bab sebelumnya untuk mencipta proses. Hanya selepas semua tugasan dalam kumpulan proses dilaksanakan, tugasan seterusnya akan dilaksanakan. Walau bagaimanapun, ia biasanya digunakan apabila kumpulan proses ditutup (close 函数).

apply_async function demonstration case

Seterusnya kami mencipta skrip dalam Pycharm untuk mempraktikkan penggunaan kumpulan proses.

  • Tentukan fungsi dan cetak bilangan kali fungsi itu dilaksanakan setiap kali dan nombor proses untuk bilangan kali itu
  • Tentukan bilangan kumpulan proses dan bilangan proses pelaksanaan setiap kali Bilangan maksimum proses yang ditetapkan untuk kumpulan proses

Kod sampel adalah seperti berikut:

# coding:utf-8import osimport timeimport multiprocessingdef work(count):    
# 定义一个 work 函数,打印输出 每次执行的次数 与 该次数的进程号
    print('\'work\' 函数 第 {} 次执行,进程号为 {}'.format(count, os.getpid()))
    time.sleep(3)
    # print('********')if __name__ == '__main__':
    pool = multiprocessing.Pool(3)      
    # 定义进程池的进程数量,同一时间每次执行最多3个进程
    for i in range(21):
        pool.apply_async(func=work, args=(i,))      
        # 传入的参数是元组,因为我们只有一个 i 参数,所以我们要写成 args=(i,)

    time.sleep(15)      
    # 这里的休眠时间是必须要加上的,否则我们的进程池还未运行,主进程就已经运行结束,对应的进程池也会关闭。
Salin selepas log masuk

Hasil yang dijalankan adalah seperti berikut:


Ketahui lebih lanjut tentang kumpulan proses Python dan kunci proses

Daripada gambar di atas, kita dapat melihat bahawa tiga proses dijalankan serentak setiap kali Nombor proses setiap proses adalah berbeza, tetapi jika anda lihat dengan teliti, anda akan mendapati bahawa nombor proses yang sama wujud, yang menunjukkan bahawa ID proses kumpulan proses sedang digunakan semula. Ini membuktikan apa yang kami perkenalkan di atas, proses dalam kumpulan proses tidak akan ditutup dan boleh digunakan berulang kali.

Dan kami juga dapat melihat bahawa 3 proses dilaksanakan setiap 3 saat Sebabnya ialah hanya terdapat 3 proses dalam kumpulan proses kami; walaupun terdapat 21 tugas dalam for 循环 kami, fungsi kerja akan menjadi Dilaksanakan 21 kali, tetapi kerana kita hanya mempunyai 3 proses dalam kumpulan proses. Jadi selepas melaksanakan 3 tugasan (tidur selama 3 saat), tugasan seterusnya akan menunggu proses dalam kumpulan proses melahu sebelum meneruskan pelaksanaan.

Begitu juga, terdapat perbezaan tertentu dalam susunan nombor proses Sebabnya adalah kerana kami menggunakan kaedah 异步 (tak segerak atau tidak segerak). Ini menyebabkan ketiga-tiga tugasan work 函数 dilaksanakan bersama menjadi tidak teratur, itulah sebabnya nombor proses kami berada dalam susunan yang tidak konsisten. (更多的异步知识我们会在异步的章节进行详细介绍)

进程池的原理: 上述脚本的案例证实了我们进程池关于进程的限制,只有当我们进程池中的进程处于空闲状态的时候才会将进程池外等待的任务扔到进程池中工作。


Tutup fungsi dan sertai demonstrasi fungsi

Dalam skrip di atas, kami menggunakan time.sleep(15) membantu kami menyekat proses utama selama 15 saat dan keluar semula, sekali gus memberikan kumpulan proses kami masa yang mencukupi untuk menyelesaikan tugas gelung fungsi kerja() kami.

Bagaimana jika tiada ayat time.sleep(15) sebenarnya, fungsi join proses boleh digunakan di sini. Walau bagaimanapun, seperti yang kami nyatakan di atas, fungsi join() sesuatu proses biasanya digunakan apabila kumpulan proses ditutup (close 函数). Seterusnya, mari cuba gantikan time.sleep(15) dalam skrip di atas dengan fungsi join().

Kod sampel adalah seperti berikut:

# coding:utf-8import osimport timeimport multiprocessingdef work(count):    
# 定义一个 work 函数,打印输出 每次执行的次数 与 该次数的进程号
    print('\'work\' 函数 第 {} 次执行,进程号为 {}'.format(count, os.getpid()))
    time.sleep(3)
    # print('********')if __name__ == '__main__':
    pool = multiprocessing.Pool(3)      # 定义进程池的进程数量,同一时间每次执行最多3个进程
    for i in range(21):
        pool.apply_async(func=work, args=(i,))      
        # 传入的参数是元组,因为我们只有一个 i 参数,所以我们要写成 args=(i,)

    # time.sleep(15) 
    pool.close()
    pool.join()
Salin selepas log masuk

Hasil larian adalah seperti berikut:


Ketahui lebih lanjut tentang kumpulan proses Python dan kunci proses

Seperti yang kita boleh lihat daripada animasi di atas , tugasan fungsi work() dan proses dalam kumpulan proses adalah konsisten dengan hasil penggunaan time.sleep(15).

PS: Jika proses utama kami akan sentiasa dilaksanakan, ia tidak akan keluar. Kemudian kita tidak perlu menambah close() 与 join() 函数, kita boleh mengekalkan kumpulan proses bermula sehingga tugasan masuk dan ia akan dilaksanakan.

Selepas mempelajari pembangunan WEB kemudian, adalah perkara biasa untuk bekerja tanpa keluar dari proses utama. Terdapat juga beberapa tugasan yang perlu dilaksanakan dalam jangka masa yang lama dan tidak akan ditutup, tetapi jika hanya terdapat skrip pelaksanaan sekali sahaja, anda perlu menambah close() 与 join() 函数 untuk memastikan proses utama keluar selepas semua tugasan dalam kolam proses selesai. Sudah tentu, jika proses utama ditutup, ia tidak lagi menerima tugas baru, yang bermaksud berakhirnya kumpulan proses.


Mari lihat contoh lain, menambah pulangan dalam work 函数.

Anda mungkin mempunyai soalan di sini Dalam bab sebelumnya, titik pengetahuan tentang proses tersebut dengan jelas disebut 进程无法获取返回值, jadi apakah kepentingan work() yang ditambahkan pada fungsi return di sini?

其实不然,在我们的使用进程池的 apply_async 方法时,是通过异步的方式实现的,而异步是可以获取返回值的。针对上述脚本,我们在 for循环中针对每一个异步 apply_async 添加一个变量名,从而获取返回值。

示例代码如下:

# coding:utf-8import osimport timeimport multiprocessingdef work(count):    # 定义一个 work 函数,打印输出 每次执行的次数 与 该次数的进程号
    print('\'work\' 函数 第 {} 次执行,进程号为 {}'.format(count, os.getpid()))
    time.sleep(3)
    return '\'work\' 函数 result 返回值为:{}, 进程ID为:{}'.format(count, os.getpid())if __name__ == '__main__':
    pool = multiprocessing.Pool(3)      # 定义进程池的进程数量,同一时间每次执行最多3个进程
    results = []
    for i in range(21):
        result = pool.apply_async(func=work, args=(i,))      # 传入的参数是元组,因为我们只有一个 i 参数,所以我们要写成 args=(i,)
        results.append(result)

    for result in results:
        print(result.get())     # 可以通过这个方式返回 apply_async 的返回值,
                                # 通过这种方式也不再需要 使用 close()、join() 函数就可以正常执行。

    # time.sleep(15)      # 这里的休眠时间是必须要加上的,否则我们的进程池还未运行,主进程就已经运行结束,对应的进程池也会关闭。
    # pool.close()
    # pool.join()
Salin selepas log masuk

运行结果如下:


Ketahui lebih lanjut tentang kumpulan proses Python dan kunci proses

从运行结果可以看出,首先 work() 函数被线程池的线程执行了一遍,当第一组任务执行完毕紧接着执行第二次线程池任务的时候,打印输出了 apply_async 的返回值,证明返回值被成功的返回了。然后继续下一组的任务…

这些都是主要依赖于 异步 ,关于 异步 的更多知识会在 异步 的章节进行详细的介绍。


进程锁

 进程锁的概念

锁:大家都知道,我们可以给一个大门上锁。

结合这个场景来举一个例子:比如现在有多个进程同时冲向一个 "大门" ,当前门内是没有 "人"的(其实就是进程),锁也没有锁上。当有一个进程进去之后并且把 “门” 锁上了,这时候门外的那些进程是进不来的。在门内的 “人” ,可以在 “门” 内做任何事情且不会被干扰。当它出来之后,会解开门锁。这时候又有一个 “人” 进去了门内,并且重复这样的操作,这就是 进程锁。它可以让锁后面的工作只能被一个任务来处理,只有它解锁之后下一个任务才会进入,这就是 “锁” 的概念。

进程锁 就是仅针对于 进程 有效的锁,当进程的任务开始之后,就会被上一把 “锁”;与之对应的是 线程锁 ,它们的原理几乎是一样的。

进程锁的加锁与解锁

进程锁的使用方法:

通过 multiprocessing 导入 Manager 类

from multiprocessing import Manager

然后实例化 Manager

manager = Manager()

再然后通过实例化后的 manager 调用 它的 Lock() 函数

lock = manager.Lock()

接下来,就需要操作这个 lock 对象的函数

函数名 介绍 参数 返回值
acquire 上锁
release 解锁(开锁)

代码示例如下:

# coding:utf-8import osimport timeimport multiprocessingdef work(count, lock):    # 定义一个 work 函数,打印输出 每次执行的次数 与 该次数的进程号,增加线程锁。
    lock.acquire()        # 上锁
    print('\'work\' 函数 第 {} 次执行,进程号为 {}'.format(count, os.getpid()))
    time.sleep(3)
    lock.release()        # 解锁
    return '\'work\' 函数 result 返回值为:{}, 进程ID为:{}'.format(count, os.getpid())if __name__ == '__main__':
    pool = multiprocessing.Pool(3)      # 定义进程池的进程数量,同一时间每次执行最多3个进程
    manager = multiprocessing.Manager()
    lock = manager.Lock()
    results = []
    for i in range(21):
        result = pool.apply_async(func=work, args=(i, lock))      # 传入的参数是元组,因为我们只有一个 i 参数,所以我们要写成 args=(i,)
        # results.append(result)


    # time.sleep(15)      # 这里的休眠时间是必须要加上的,否则我们的进程池还未运行,主进程就已经运行结束,对应的进程池也会关闭。
    pool.close()
    pool.join()
Salin selepas log masuk

执行结果如下:


Ketahui lebih lanjut tentang kumpulan proses Python dan kunci proses

从上图中,可以看到每一次只有一个任务会被执行。由于每一个进程会被阻塞 3秒钟,所以我们的进程执行的非常慢。这是因为每一个进程进入到 work() 函数中,都会执行 上锁、阻塞3秒、解锁 的过程,这样就完成了一个进程的工作。下一个进程任务开始,重复这个过程… 这就是 进程锁的概念


其实进程锁还有很多种方法,在 multiprocessing 中有一个直接使用的锁,就是 ``from multiprocessing import Lock。这个Lock的锁使用和我们刚刚介绍的Manager` 的锁的使用有所区别。(这里不做详细介绍,感兴趣的话可以自行拓展一下。)

的使用可以让我们对某个任务 在同一时间只能对一个进程进行开发,但是 锁也不可以乱用 。因为如果某些原因造成 锁没有正常解开 ,就会造成死锁的现象,这样就无法再进行操作了。

因为 锁如果解不开 ,后面的任务也就没有办法继续执行任务,所以使用锁一定要谨慎。

推荐学习:python视频教程

Atas ialah kandungan terperinci Ketahui lebih lanjut tentang kumpulan proses Python dan kunci proses. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:csdn.net
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan