Python 多进程、线程、协程的简单使用

多线程 进程 协程

01 threading实现多线程

  1. 导入threading模块
    import threading

  2. 创建对象

    def sing():
        for i in range(5):
            print("------Singing-----")
            time.sleep(1)
            
    ts = threading.Thread(target=sing)
    

    注意 target参数只写函数名,不能加括号,此时只创建了对象,没有创建线程

  3. 控制子线程

    ts.start()  # 启动子线程
    ts.join([time])  # 等待子线程运行完成
    ts.isAlive()  # 返回子线程是否是存活的
    ts.getName()  # 返回子线程名
    ts.setName()  # 设置子线程名
    

    调用start之后才创建了子线程,子线程从start开始执行,目标函数结束后子线程运行结束

  4. 运行多个子线程

    while True:
      length=len(threading.enumerate())
      # print("\n当前运行的进程数:%d\n"%length)
      time.sleep(2)
      if length <= 1:
            print("\n所有子线程已运行完成!!!\n")
            break
    

    len(threading.enumerate())表示当前运行的线程数,包括一个主线程

  5. 通过重载使用多线程

    import threading
    import time
    
    class MyThread(threading.Thread):
        def run(self):
            for i in range(3):
                time.sleep(1)
                print("-----%d-----"%i)
            self.relax()
    
        def relax(self):
            print('-----relax-----\n')
    
    if __name__=='__main__':
        t=MyThread()
        t.start()  
    

    调用start时会自动调用类中的run,因此在类中必须定义run

  6. 互斥锁

    • 创建锁(默认是不加锁的) mutex=threading.Lock()
    • 上锁 mutex.acquire()
    • 解锁 mutex.release()
    • 判断是否上锁 mutex.locker()

02 multiprocessing实现多进程

进程与线程的区别:

  • 进程是资源分配的单位,线程是资源调度的单位
  • 进程需要的资源多 线程需要的资源少
  • 进程如同一条流水线 线程如同流水线上的工人
  1. 导入模块
    import multiprocessing

  2. 创建对象

    import time
    import multiprocessing
    
    def sing():
        for i in range(5):
            print("------Singing-----")
            time.sleep(1)
            
    def dance():
        for i in range(5):
            print("------Dancing-----")
            time.sleep(1)
            
    def main():
       ts=multiprocessing.Process(target=sing)
       td=multiprocessing.Process(target=dance)
    
       ts.start()   
       td.start()  
    
    if __name__=='__main__':
        main()
    
    
    1. 调用start后才创建了子进程,子进程从start开始执行,子线程函数结束后子进程运行结束
    2. 子进程会将主进程的内存复制,复制变量的值。 代码是共享的,不复制 复制的越少越好,能共享就共享
  3. queue实现进程间通信

    import multiprocessing
    
    # 模拟下载数据
    def download_data(q):
        data=[1,2,3,4,5]
        for temp in data:
            q.put(temp)
    
        print('所有数据已经存入!')
    
    # 模拟处理数据
    def data_process(q):
        get_data=list()
        while (q.empty()==False):
            data=q.get()
            get_data.append(data)
        print(get_data)
    
    def main():
        #创建一个队列
        q=multiprocessing.Queue()  
        
        p1=multiprocessing.Process(target=download_data,args=(q,))
        p2=multiprocessing.Process(target=data_process,args=(q,))
        p1.start()
        p2.start()
    
    if __name__=='__main__':
        main()
    
      1. queue在内存中开辟空间,储存用于通信的数据
    
    1. queue只能用于同一个电脑的同一个程序

    2. 不指定队列大小时,根据内存自动确定大小

    3. 创建进程传递参数时,要注意传递的是一个元组,要加逗号

  4. 进程池
    在任务数不确定时,往往使用进程池

    import multiprocessing
    import os,time,random
    
    def job(msg):
        t_start=time.time()
        print('%s开始执行,进程号为:%d'%(msg,os.getpid()))
        time.sleep(random.random()*3)
        t_stop=time.time()
        t_cost=t_stop - t_start
        print('%s执行执行完毕,耗时%0.2fs' % (msg, t_cost))
    
    def main():
        po=multiprocessing.Pool(3)  # 设置进程池容量为3
        for i in range(10):
            po.apply_async(job,(i,))  # 两个参数为要执行的函数名和传递参数元组
    
        print('----start----')
        po.close()  # 关闭进程池
        po.join()  # 等待池中所有进程执行结束 必须在close之后
        print('----end----')
    
    if __name__=='__main__':
        main()
    
    1. 创建容纳三个进程的进程池去执行九个任务
    2. 进程池使用queue通信时,要使用manager下的queue
      如q=multiprocessing.Manager().Queue()

03 gevent实现协程

  1. gevent再遇到延时函数时会自动切换协程,但要注意需要使用gevent中的延时函数,如将time.sleep()换成gevent.sleep()
    如果想要使用原来的延时函数,可以添加语句:

     gevent.monkey.patch_all()
    
  2. 启动多个协程的方法

    gevent.joinall(
        [
            gevent.spawn(f1,5),
            gevent.spawn(f2,5),
            gevent.spawn(f3,5)  # 设置目标函数并传递参数
        ]
    )
    

    协程传递参数使用的不是元组

  3. 代码示例

    from gevent import monkey
    
    gevent.monkey.patch_all()
    
    def f1(n):
        for i in range(n):
            print('f1:',i)
            time.sleep(1)
    
    def f2(n):
        for i in range(n):
            print('f2:',i)
            time.sleep(1)
    
    def f3(n):
        for i in range(n):
            print('f3:',i)
            time.sleep(1)
    
    
    gevent.joinall(
        [
            gevent.spawn(f1,5),
            gevent.spawn(f2,5),
            gevent.spawn(f3,5)
        ]
    )
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容