zoukankan      html  css  js  c++  java
  • python learning Process and Thread.py

    # 多进程
    # Windows下面没有fork ,请在linux下跑下面的代码
    
    import os
    
    print('Process (%s) start...' % os.getpid())
    
    pid = os.fork()
    if pid==0:
        print('I am child process (%s) and my parent is %s' % (os.getpid(), os.getppid())
    else:
        print('I (%s) just created a child process(%s).' % (os.getpid(), pid))
    
    

    # windows 下没有 fork,实现多进程要使用 multiprocessing 模块
    
    from multiprocessing import Process
    import os, time
    
    def run_proc(name):
        print('Run child process %s (%s)...' % (name, os.getpid()))
    
    if __name__=='__main__':
        print('Parent process %s.' % os.getpid())
        p = Process(target=run_proc, args=('test',)) # target 将函数作为单个进程,args 是传参数
        print('Child process will start.')
        p.start() # 启动
        p.join() # 等待子进程结束后继续运行
        print('Child process is end.')
        print('..................')
        time.sleep(1)
    
    
    # Pool
    # 要启动大量的子进程,可以用进程池的方式批量创建子进程:
    
    from multiprocessing import Pool
    import os, time, random
    
    def long_time_task(name):
        print('Run task %s (%s)' % (name, os.getpid()))
        start = time.time() # 返回当前时间的时间戳
        time.sleep(random.random() * 3)  # random() 方法返回随机生成的一个实数,它在[0,1)范围内。
        end = time.time()
        print('Task %s runs %0.2f seconds' % (name, (end-start)))
    
    if __name__ == '__main__':
        print('Parent process %s.'% os.getpid())
        p = Pool(3)
        for i in range(4):
            p.apply_async(long_time_task, args=(i,))
        print('waiting for all subprocesses done...')
        p.close()
        p.join()
        print('Done')
        print('..................')
        time.sleep(1)
    
    # 对Pool对象调用join()方法会等待所有子进程执行完毕,调用join()之前必须先调用close(),调用close()之后就不能继续添加新的Process了。
    
    
    
    # 进程间通信
    
    # Python的multiprocessing模块包装了底层的机制,提供了Queue、Pipes等多种方式来交换数据。
    
    # 参考链接:https://www.cnblogs.com/kaituorensheng/p/4445418.html#_label5
    
    from multiprocessing import Process, Queue
    import os, time, random
    
    # 写数据进程执行的代码:
    def write(q):
        print('Process to write: %s' % os.getpid())
        for value in ['a','b','c']:
            print('Put %s to queue...' % value)
            q.put(value)
            time.sleep(random.random())
    
    # 读
    def read(q):
        print('Process to read: %s' % os.getpid())
        while True:
            value = q.get(True)
            print('Gets %s from queue.' % value)
    
    if __name__ == '__main__':
        # 父进程创建队列,传递给各个子进程
        q = Queue()
        pw = Process(target=write, args=(q,))
        pr = Process(target=read, args=(q,))
    
        pw.start()
        pr.start()
        pw.join()
        pr.terminate() # pr进程里是死循环,无法等待其结束,只能强行终止:
        print('Done')
        print('..................')
        time.sleep(1)
    
    
    ##############################################################
    
    # 多线程
    
    '''
    多任务可以由多进程完成,也可以由一个进程内的多线程完成。
    
    我们前面提到了进程是由若干线程组成的,一个进程至少有一个线程。
    
    由于线程是操作系统直接支持的执行单元,因此,高级语言通常都内置多线程的支持,Python也不例外,并且,Python的线程是真正的Posix Thread,而不是模拟出来的线程。
    '''
    
    # Python的标准库中,绝大多数情况下,我们只需要使用threading这个高级模块。
    
    # 启动一个线程就是把一个函数传入并创建Thread实例,然后调用start()开始执行:
    
    import time, threading
    
    # 新进程执行的代码:
    
    def loop():
        print('thread %s is running ...' % threading.current_thread().name)
        n = 0
        while n < 3:
            n = n + 1
            print('thread %s >>> %s' % (threading.current_thread().name,n))
            time.sleep(1)
        print('thread %s ended.' % threading.current_thread().name)
    
    print('thread %s is running ...' % threading.current_thread().name)
    t = threading.Thread(target=loop, name='LoopTread') # 子线程的名字在创建时指定,我们用LoopThread命名子线程。名字仅仅在打印时用来显示,完全没有其他意义
    t.start()
    t.join()
    print('thread %s ended.' % threading.current_thread().name)
    
    # 任何进程默认就会启动一个线程,我们把该线程称为主线程,主线程又可以启动新的线程
    # current_thread()函数,它永远返回当前线程的实例。
    
    
    # Lock
    
    # 多线程和多进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,
    # 而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改,因此,线程之间共享数据最大的危险在于多个线程同时改一个变量,把内容给改乱了。
    
    
    # 假定这是你的银行存款:
    balance = 0
    
    def change_it(n):
        # 先存后取,结果应该为0:
        global balance # 告诉Python这个变量名不是局部的,而是 全局 的
        ###
        balance = balance + n
        balance = balance - n
        ### 这两句语句在一个线程里应该是要连续执行才对
    
    def run_thread(n):
        for i in range(5000000):
            change_it(n)
    
    t1 = threading.Thread(target=run_thread,args=(5,))
    t2 = threading.Thread(target=run_thread,args=(8,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print(balance) # 由于线程的调度是由操作系统决定的,当t1、t2交替执行时,只要循环次数足够多,balance的结果就不一定是0了。
    print('Done.......................')
    
    
    # 为函数 change_it 添加一个锁
    # 当某个线程开始执行change_it()时,该线程因为获得了锁,因此其他线程不能同时执行change_it(),只能等待,直到锁被释放后,获得该锁以后才能执行。
    
    balance = 0
    lock = threading.Lock()
    
    def run_thread(n):
        for i in range(5000000):
            # p(信号量)
            lock.acquire()
            try:
                change_it(n)
            finally:
                # v(信号量)
                lock.release()
    
    print(balance)
    print('Done.......................')
    
    
  • 相关阅读:
    python3+requests库框架设计03-请求重新封装
    python3+requests库框架设计02-封装日志类
    [patl2-001]紧急救援
    [patl1-046]整除光棍
    latex学习
    matlab基础功能实践
    dll注入及卸载实践
    编译原理大作业暂存
    12.24逆向工程上机作业整理
    [poj1703]Find them, Catch them(种类并查集)
  • 原文地址:https://www.cnblogs.com/ZCplayground/p/9026428.html
Copyright © 2011-2022 走看看