• Python3.x基础学习-线程和进程(一)


    线程与进程

    1 定义:

    并发:任务数大于核心数,通过操作系统调度算法实现多个任务“一起执行”
    实际是通过快速1切换任务,看上去是一起执行

    并行:任务数小于核心数,任务是真正一起执行的

    2 程序:不运行的软件是程序

    进程:运行起来的应用程序就是进程
    程序只有一个,但是进程可以有多个

    3 创建进程

    from multiprocessing import Process

    p = Process(target = func,args=(num,),kwargs={})
    p.start() # 执行子进程
    p.join() 等待子进程执行结束

    4 进程pid

    当前进程os.getpid(),父进程 os.getppid()

    5 进程之间的通信

    1 创建queue队列对象
    q=multiprocessing.Queue(3) # 3表示只能存放3个数据
    参数:maxsize是队列中允许的最大项数。如果省略此参数,则无大小限制。返回值q是队列对象
    2. put()方法,向队列中存放数据。如果队列已满,此方法将阻塞至有空间可用为止
    3. get()返回q中的一个项目。如果q为空,此方法将阻塞,直到队列中有项目可用为止
    4. get_nowait():不等待,直接抛出异常
    5. full()如果q已满,返回为True
    6. q.empty()如果调用此方法时q为空,返回为True
    7. q.size()获取队列中数据的个数

    6.进程池

    使用multiprocessing模块中的Pool类,也就是进程池
    from multiprocessing import Pool
    pool = Pool(3)
    pool.apply_async(func(i,),callback=alert)
    # apply_async以非阻塞的形式创建进程 # apply阻塞
    callback回调函数 将func的返回值传给alert

    7.进程池中进程之间的通信,

    使用from multiprocessing import Manager中的Queue
    而不是multiprocessing中的Queue
    q = Manager().Queue()

    8.一个程序运行起来至少有一个进程,一个进程至少有一个线程

    线程是cpu调度的最小单位,进程是操作系统分配的资源单位
    进程比线程耗资源
    线程可以共享进程中的资源

    9. 创建线程 threading模块

    join();当前线程执行完之后其他线程才会继续执行

    进程

    # 先下载歌曲,再听歌
    
    import time
    
    def down_load():
        for i in range(1,5):
            print("正在下载歌曲")
            time.sleep(0.5)
    
    def listen():
        for i in range(1,5):
            print("正在听歌")
            time.sleep(1)
    
    start = time.time()
    down_load()
    listen()
    
    end = time.time()
    
    total_time = end -start
    # print('总共花了%ss'%total_time)
    # 总共花了6.037492513656616s
    import time
    from multiprocessing import Process
    
    def down_load():
        for i in range(1,5):
            print("正在下载歌曲")
            time.sleep(0.5)
    
    def listen():
        for i in range(1,5):
            print("正在听歌")
            time.sleep(1)
    
    def main():
        p1 = Process(target=down_load)  #创建子进程
        p2 = Process(target=listen)
        start = time.time()
        p1.start()  #开启子进程
        p2.start()
        p1.join()  #等待子进程执行结束
        p2.join()
        end = time.time()
        total_time = end -start
        print('总共花了%ss'%total_time)
    
    if __name__ == '__main__':
        main()
        # 总共花了4.157751083374023s
    # 进程pid 当前进程 os.getpid(),父进程os.getppid()
    
    from multiprocessing import Process
    import os
    import time
    
    def func():
        while True:
            time.sleep(1)
            print('---func---子进程为{},父进程为{}'.format(os.getpid(),os.getppid()))
    
    if __name__ == '__main__':
        print("---main--主进程为{},主进程的父进程{}".format(os.getpid(),os.getppid()))
        p1 = Process(target=func)
        p1.start()
    # 给子进程传递响应的参数 args = (),kwargs={}
    import os
    from  multiprocessing import Process
    
    def func(name,age,**kwargs):
        print("--func--子进程为name=%s,pid=%d"%(name,os.getpid()))
        print(age)
        print(kwargs)
    
    if __name__ == '__main__':
        p1 = Process(target=func,args=('johnson',22),kwargs={'weight':123})
        p1.start()
        
    # --func--子进程为name=johnson,pid=10708
    # 22
    # {'weight': 123}
    # 进程间不共享全局变量
    import multiprocessing
    list = [1,2,3]
    
    def func1():
        for i in range(1,5):
            list.append(i)
        print('func1:',list)
    def func2():
        print('func2:',list)
    
    if __name__ == '__main__':
        process1 = multiprocessing.Process(target=func1)
        process2 = multiprocessing.Process(target=func2)
        process1.start()
        process2.start()
        print('外层:',list)
    
    # 外层: [1, 2, 3]
    # func1: [1, 2, 3, 1, 2, 3, 4]
    # func2: [1, 2, 3]

    queue相关用法

    from multiprocessing import Queue
    
    q = Queue(3)  # 创建对象,最多放三条数据
    print(q.empty())
    
    q.put("johnson")
    print(q.empty())
    
    q.put("mary")
    q.put("way")
    print(q.full())
    
    # print(q.get())
    # print(q.get())
    # print(q.get())
    # print(q.get())
    # print(q.get_nowait())
    print(q.qsize())
    from multiprocessing import Queue
    import multiprocessing
    import time
    
    def down_load(q):
        data = ['a','b','c']
        for i in data:
            time.sleep(0.5)
            q.put(i)
        print("下载完了数据")
    
    def work(q):
        for i  in range(q.qsize()):
            print(q.get())
        print("处理完了数据")
    
    if __name__ == '__main__':
        q = Queue()
        p1 = multiprocessing.Process(target=down_load,args=(q,))
        p2 = multiprocessing.Process(target=work,args=(q,))
        p1.start()
        p2.start()
    from multiprocessing import  Queue
    import multiprocessing
    import time
    
    def down_load(q):
        data = ['a','b','c']
        for i in data:
            time.sleep(0.5)
            q.put(i)
        print("下载完了数据")
    
    def work(q):
        while True:
            print(q.get())
        print('处理完了数据')
    
    if __name__ == '__main__':
        q = Queue()
        p1 = multiprocessing.Process(target=down_load,args=(q,))
        p2 = multiprocessing.Process(target=work,args=(q,))
        p1.start()
        p2.start()
    
    # a
    # b
    # 下载完了数据
    # c

    Pool相关用法

    from multiprocessing import Pool
    
    def down_load(movie_name):
        for i in range(5):
            print("电影{},下载进度{}%".format(movie_name,i/4*100))
            time.sleep(1)
        return movie_name+'--->'
    
    def alert(movie_name):
        print("恭喜{}下载完成了。。。。".format(movie_name))
    
    if __name__ == '__main__':
        movie_lst = ['西红柿首富', '功夫小子', '功夫熊猫', '叶问', '功 夫', '战狼', '红海行动']
        pool = Pool(4)
        for movie_name in movie_lst:
            pool.apply_async(down_load,(movie_name,),callback=alert)  # 以非阻塞的形式创建进程
    
        pool.close()
        pool.join()
    
    # 电影西红柿首富,下载进度0.0%
    # 电影功夫小子,下载进度0.0%
    # 电影功夫熊猫,下载进度0.0%
    # 电影叶问,下载进度0.0%
    # 电影西红柿首富,下载进度25.0%
    # 电影功夫小子,下载进度25.0%
    # 电影功夫熊猫,下载进度25.0%
    # 电影叶问,下载进度25.0%
    # 电影西红柿首富,下载进度50.0%
    # 电影功夫小子,下载进度50.0%
    # 电影功夫熊猫,下载进度50.0%
    # 电影叶问,下载进度50.0%
    # 电影西红柿首富,下载进度75.0%
    # 电影功夫小子,下载进度75.0%
    # 电影功夫熊猫,下载进度75.0%
    # 电影叶问,下载进度75.0%
    # 电影西红柿首富,下载进度100.0%
    # 电影功夫小子,下载进度100.0%
    # 电影功夫熊猫,下载进度100.0%
    # 电影叶问,下载进度100.0%
    # 电影功 夫,下载进度0.0%
    # 恭喜西红柿首富--->下载完成了。。。。
    # 电影战狼,下载进度0.0%
    # 恭喜功夫小子--->下载完成了。。。。
    # 恭喜功夫熊猫--->下载完成了。。。。
    # 电影红海行动,下载进度0.0%
    # 恭喜叶问--->下载完成了。。。。
    # 电影功 夫,下载进度25.0%
    # 电影战狼,下载进度25.0%
    # 电影红海行动,下载进度25.0%
    # 电影功 夫,下载进度50.0%
    # 电影战狼,下载进度50.0%
    # 电影红海行动,下载进度50.0%
    # 电影功 夫,下载进度75.0%
    # 电影战狼,下载进度75.0%
    # 电影红海行动,下载进度75.0%
    # 电影功 夫,下载进度100.0%
    # 电影战狼,下载进度100.0%
    # 电影红海行动,下载进度100.0%
    # 恭喜功 夫--->下载完成了。。。。
    # 恭喜战狼--->下载完成了。。。。
    # 恭喜红海行动--->下载完成了。。。。
    # 验证上面始终只有三个进程号
    
    from multiprocessing import Pool
    import os,time,random
    
    def func(i):
        start = time.time()
        print('%d开始执行,子进程号是%d,父进程号%d'%(i,os.getpid(),os.getppid()))
        time.sleep(random.random()*2)
        end = time.time()
        print("%d执行完毕,耗时%.2f"%(i,end-start))
    
    if __name__ =="__main__":
        pool = Pool(3)
        print("主进程号:",os.getpid())
        for i in range(10):
            pool.apply_async(func,(i,))
        pool.close()
        pool.join()
        print('-------end------')
        
    # 主进程号: 5800
    # 0开始执行,子进程号是15944,父进程号5800
    # 1开始执行,子进程号是8916,父进程号5800
    # 2开始执行,子进程号是16348,父进程号5800
    # 2执行完毕,耗时1.17
    # 3开始执行,子进程号是16348,父进程号5800
    # 3执行完毕,耗时0.14
    # 4开始执行,子进程号是16348,父进程号5800
    # 0执行完毕,耗时1.50
    # 5开始执行,子进程号是15944,父进程号5800
    # 1执行完毕,耗时1.60
    # 6开始执行,子进程号是8916,父进程号5800
    # 4执行完毕,耗时0.29
    # 7开始执行,子进程号是16348,父进程号5800
    # 6执行完毕,耗时1.01
    # 8开始执行,子进程号是8916,父进程号5800
    # 7执行完毕,耗时1.40
    # 9开始执行,子进程号是16348,父进程号5800
    # 5执行完毕,耗时1.78
    # 8执行完毕,耗时1.99
    # 9执行完毕,耗时1.81
    # -------end------

    进程间通信

    import os
    
    from multiprocessing import Manager
    from multiprocessing import Pool
    
    import time
    
    def write(q):
        print('write子进程%d启动,父进程%d'%(os.getpid(),os.getppid()))
        for i in "python1234":
            time.sleep(0.5)
            q.put(i)
    
    def reader(q):
        print("reader子进程%d启动,父进程%d"%(os.getpid(),os.getppid()))
        time.sleep(1)
        for i in range(q.qsize()):
            time.sleep(0.5)
            print(q.get())
    
    
    if __name__ == '__main__':
        print("主进程执行%d"%os.getpid())
        q = Manager().Queue()
        pool = Pool(3)
        pool.apply_async(write,(q,))
        time.sleep(1)
        pool.apply_async(reader,(q,))
        pool.close()
        pool.join()
    
    # 主进程执行3140
    # write子进程9264启动,父进程3140
    # reader子进程10608启动,父进程3140
    # p
    # y
    # t

    线程

    from threading import Thread
    import time
    
    def down_load():
        for i in range(1,5):
            print("正在下载歌曲")
            time.sleep(0.5)
    
    def listen():
        for i in range(1,5):
            print("正在听歌")
            time.sleep(1)
    
    t1 = Thread(target=down_load)
    t2 = Thread(target=listen)
    
    start = time.time()
    
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    end = time.time()
    
    print("耗时:",end-start,"s")
    
    # 正在下载歌曲
    # 正在听歌
    # 正在下载歌曲
    # 正在听歌
    # 正在下载歌曲
    # 正在下载歌曲
    # 正在听歌
    # 正在听歌
    # 耗时: 4.002870082855225 s
    from threading import Thread
    import time
    
    list = [11,22]
    
    def func1():
        list.append(33)
    
    def func2():
        time.sleep(1)
        print('--func2--',list)
    
    t1 = Thread(target=func1)
    t2 = Thread(target=func2)
    t1.start()
    t2.start()
    print("main--:",list)
    
    # main--: [11, 22, 33]
    # --func2-- [11, 22, 33]
  • 相关阅读:
    rapidjson代码封装类
    CEF3.2623使用记录:windows编译
    ACE主动对象模式
    理解i++和++i
    ubuntu安装vmplayer出现问题的解决方法
    WinSpy涉及的windows api
    winXP下安装opensshd服务
    资源下载链接
    FPM打包工具
    mysql error code
  • 原文地址:https://www.cnblogs.com/johnsonbug/p/12710019.html
Copyright © 2020-2023  润新知