ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

进程、线程、协程嵌套出现内层程序丢失

2022-03-30 11:01:50  阅读:156  来源: 互联网

标签:协程 gevent1 gevent2 list 嵌套 gevent 线程 print


进程、线程、协程嵌套出现内层程序丢失

复现

import time

import gevent
from gevent import monkey, spawn;

monkey.patch_all()
from concurrent.futures import ThreadPoolExecutor


def func1_gevent():
    time.sleep(5)

    print('gevent1')


def func2_gevent():
    time.sleep(3)

    print('gevent2')


def func_thread(gevent_list):
    time.sleep(5)
    feature_gevent = spawn(func1_gevent)
    gevent_list.append(feature_gevent)

    func2_gev = spawn(func2_gevent)
    gevent_list.append(func2_gev)


def main():
    gevent_list = list()
    pool = ThreadPoolExecutor(20)
    for i in range(10):
        pool.submit(func_thread, gevent_list)

    print(len(gevent_list))
    gevent.joinall(gevent_list)
    print(len(gevent_list))
    pool.shutdown(wait=True)
    
    print('asdfasdfasdf')


if __name__ == '__main__':
    main()

    
## 运行结果
#0
#0
#asdfasdfasdf

 

原因

此时,线程池中的线程都submit了,但是线程并未开始执行,停留在time.sleep

==> 在gevent.joinall()时,gevent_list中并没有append任何协程对象,它的length为0,导致监听程序认为所有协程都已执行完成

==> pool.shutdown(wait=True)表示等待线程池中的所有线程中的 主程序 都执行结束,再向下执行主进程。这里会等time.sleep结束,并执行append结束,它并不会判断gevent是否已经结束

==> 在执行print('asdfasdfasdf')主进程的时候,可能之前的 gevent 并没有全部执行结束

==> 等待所有线程执行结束,开始执行主进程(即print('asdfasdfasdf')),然后退出主进程,此时的gevent可能刚开始执行,导致部分gevent程序丢失

 

解决方案

先执行pool.shutdown,再执行gevent.joinall

  • 先等待线程中的主程序执行完,此时所有的gevent都已经appendgevent_list
  • 然后开始joinall,此时gevent_list已包含所有需执行或正在执行的gevent,所以主进程会等所有gevent结束
def main():
    gevent_list = list()
    pool = ThreadPoolExecutor(20)
    for i in range(10):
        pool.submit(func_thread, gevent_list)
	
    
    # print(len(gevent_list))
    # gevent.joinall(gevent_list)
    # print(len(gevent_list))
    # pool.shutdown(wait=True)
    
    print(len(gevent_list))
    pool.shutdown(wait=True)
    print(len(gevent_list))
    gevent.joinall(gevent_list)
    
    print('asdfasdfasdf')

# 修改后运行结果
#0
#20
#gevent2
#gevent2
#gevent2
#gevent2
#gevent2
#gevent2
#gevent2
#gevent2
#gevent2
#gevent2
#gevent1
#gevent1
#gevent1
#gevent1
#gevent1
#gevent1
#gevent1
#gevent1
#gevent1
#gevent1
#asdfasdfasdf

标签:协程,gevent1,gevent2,list,嵌套,gevent,线程,print
来源: https://www.cnblogs.com/linagcheng/p/16075905.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有