• python---线程与进程


    一 线程

    1.1 概述

      线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。

    Threading用于提供线程相关的操作:

    import threading
    import time
    
    def show(arg):
        time.sleep(1)
        print ('thread'+str(arg))
    
    for i in range(10):
        t = threading.Thread(target=show, args=(i,))
        t.start()
    
    print ('main thread stop')
    
    >>>main thread stop
    >>>thread0
    >>>thread6
    >>>thread3
    >>>thread2
    >>>thread5
    >>>thread4
    >>>thread1
    >>>thread7
    >>>thread8
    >>>thread9

    上述代码创建了10个“前台”线程,然后控制器就交给了CPU,CPU根据指定算法进行调度,分片执行指令。

    注:后台线程行为: 只要你的主线程执行完毕了,后台线程,不管你执行到哪里了,就直接关闭了。前台线程行为: 主程序执行过程中,前台线程也在执行,主程序执行完毕后,等待前台线程也执行完成后,程序结束。

    start         #线程准备就绪,等待CPU调度
    setName       #为线程设置名称
    getName       #获取线程名称
    setDaemon     #设置为后台线程或前台线程(默认),如果是后台线程,主线程执行过程中,后台线程也在进行,主线程执行完毕后,后台线程不论成功与否,均停止 如果是前台线程,主线程执行过程中,前台线程也在进行,主线程执行完毕后,等待前台线程也执行完成后,程序停止
    join           #逐个执行每个线程,执行完毕后继续往下执行,该方法使得多线程变得无意义
    run            #线程被cpu调度后自动执行线程对象的run方法
    更多方法

    1.2 线程锁(Lock,RLock)

      由于线程之间是进行随机调度,并且每个线程可能只执行n条执行之后,当多个线程同时修改同一条数据时可能会出现脏数据,所以,出现了线程锁 - 同一时刻允许一个线程执行操作。

    import threading
    import time
    
    gl_num = 0
    
    def show(arg):
        global gl_num
        time.sleep(1)
        gl_num +=1
        print (gl_num,end=' ')
    
    for i in range(10):
        t = threading.Thread(target=show, args=(i,))
        t.start()
    
    print ('main thread stop')
    
    >>>main thread stop
    >>>1 2 3 4 5 6 7 8 9 10 
    未使用锁
    import threading
    import time
    
    gl_num = 0
    
    lock = threading.RLock()
    
    def Func():
        lock.acquire()
        global gl_num
        gl_num +=1
        time.sleep(1)
        print (gl_num)
        lock.release()
    
    for i in range(10):
        t = threading.Thread(target=Func)
        t.start()
    线程锁

    1.3 信号量(semaphore)

      多线程编程的最常见问题是数据共享。当多个线程都修改某一个共享数据的时候,需要进行同步控制。线程同步能够保证多个线程安全访问竞争资源,最简单的同步机制是引入互斥锁。互斥锁为资源引入一个状态:锁定/非锁定。某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能更改;直到该线程释放资源,将资源的状态变成“非锁定”,其他的线程才能再次锁定该资源。互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。

      而互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据 ,比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去。

    import threading,time
    
    def run(n):
        semaphore.acquire()
        time.sleep(2)
        print("run the thread: %s" %n)
        semaphore.release()
    
    if __name__ == '__main__':
    
        num= 0
        semaphore  = threading.BoundedSemaphore(5) #最多允许5个线程同时运行
        for i in range(20):
            t = threading.Thread(target=run,args=(i,))
            t.start()

    1.4 事件(event)

      python线程的事件用于主线程控制其他线程的执行,事件主要提供了三个方法 set、wait、clear。事件处理的机制:全局定义了一个“Flag”,clear将“Flag”设置为False,set将“Flag”设置为True。如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞,如果“Flag”值为True,那么event.wait 方法时便不再阻塞。

    import threading
    
    def do(event):
        print ('start')
        event.wait()
        print ('execute')
    
    event_obj = threading.Event()
    for i in range(10):
        t = threading.Thread(target=do, args=(event_obj,))
        t.start()
    
    event_obj.clear()
    inp = input('input:')
    if inp == 'true':
        event_obj.set()

    1.5 timer

    定时器,指定n秒后执行某操作

    from threading import Timer
    
    def hello():
        print("hello, world")
    
    t = Timer(1, hello)
    t.start()  # after 1 seconds, "hello, world" will be printed

    二 进程

    2.1 进程的创建

    from multiprocessing import  Process
    import time
    
    def worker(interval):
        n = 5
        while n > 0:
            print("The time is {0}".format(time.ctime()))
            time.sleep(interval)
            n -= 1
    
    if __name__ == "__main__":
        p = Process(target = worker, args = (3,))
        p.start()
        print ("p.pid:", p.pid)
        print ("p.name:", p.name)
        print ("p.is_alive:", p.is_alive())
    
    
    >>>p.pid: 5360
    >>>p.name: Process-1
    >>>p.is_alive: True
    >>>The time is Thu Jul 12 18:57:23 2018
    >>>The time is Thu Jul 12 18:57:26 2018
    >>>The time is Thu Jul 12 18:57:29 2018
    >>>The time is Thu Jul 12 18:57:32 2018
    >>>The time is Thu Jul 12 18:57:35 2018
    单进程
    import multiprocessing
    import time
    
    def worker_1(interval):
        print ("worker_1")
        time.sleep(interval)
        print ("end worker_1")
    
    def worker_2(interval):
        print ("worker_2")
        time.sleep(interval)
        print ("end worker_2")
    
    def worker_3(interval):
        print ("worker_3")
        time.sleep(interval)
        print ("end worker_3")
    
    if __name__ == "__main__":
        p1 = multiprocessing.Process(target = worker_1, args = (2,))
        p2 = multiprocessing.Process(target = worker_2, args = (3,))
        p3 = multiprocessing.Process(target = worker_3, args = (4,))
    
        p1.start()
        p2.start()
        p3.start()
    
        print("The number of CPU is:" + str(multiprocessing.cpu_count()))
        for p in multiprocessing.active_children():
            print("child   p.name:" + p.name + "	p.id" + str(p.pid))
        print ("END!!!!!!!!!!!!!!!!!")
    
    >>>The number of CPU is:4
    >>>child   p.name:Process-1    p.id5196
    >>>child   p.name:Process-2    p.id8680
    >>>child   p.name:Process-3    p.id2732
    >>>END!!!!!!!!!!!!!!!!!
    >>>worker_2
    >>>worker_1
    >>>worker_3
    >>>end worker_1
    >>>end worker_2
    >>>end worker_3
    多进程

    注意:(1)由于进程之间的数据需要各自持有一份,所以创建进程需要的非常大的开销。

       (2)进程各自持有一份数据,默认无法共享数据

    2.2 daemon

      子进程设置了daemon属性时,主进程结束,它们就随着结束了。(线程也有deamon操作)

    import multiprocessing
    import time
    
    def worker(interval):
        print("work start:{0}".format(time.ctime()));
        time.sleep(interval)
        print("work end:{0}".format(time.ctime()));
    
    if __name__ == "__main__":
        p = multiprocessing.Process(target = worker, args = (3,))
        p.start()
        print ("end!")
    
    >>>end!
    >>>work start:Thu Jul 12 19:12:51 2018
    >>>work end:Thu Jul 12 19:12:54 2018
    不加deamon
    import multiprocessing
    import time
    
    def worker(interval):
        print("work start:{0}".format(time.ctime()));
        time.sleep(interval)
        print("work end:{0}".format(time.ctime()));
    
    if __name__ == "__main__":
        p = multiprocessing.Process(target = worker, args = (3,))
        p.daemon = True
        p.start()
        print ("end!")
    
    >>>end!
    有deamon

     参考:https://www.cnblogs.com/yuanchenqi/articles/5733873.html

       https://www.cnblogs.com/wupeiqi/articles/5040827.html

  • 相关阅读:
    windows环境下生成ssh keys
    手写简易Ajax-结合Promise
    Microsoft 登陆微软账号一直加载不进去 解决方案整理
    win10如何开启卓越性能
    win10开启上帝模式
    解决网页禁止复制文字
    module 'sklearn' has no attribute 'svm'
    sklearn的SVM的decision_function_shape的ovo和ovr
    Can not squeeze dim[1], expected a dimension of 1
    python/numpy随机选取训练集/测试集索引
  • 原文地址:https://www.cnblogs.com/Terrypython/p/9301428.html
Copyright © 2020-2023  润新知