python多线程


import
threading import time def music(): print('begin to listen %s' % time.ctime()) time.sleep(3) print('stop to listen %s' % time.ctime()) def game(): print('begin to play %s' % time.ctime()) time.sleep(5) print('stop to play %s' % time.ctime()) if __name__ == '__main__': t1 = threading.Thread(target=music) t1.start() t2 = threading.Thread(target=game) t2.start() t1.join() #等t1线程执行完毕后才执行后面代码 print('ending')

join():在子线程完成运行之前,这个子线程的父线程将一直被阻塞。

守护线程

setDaemon(True):将线程声明为守护线程,必须在start() 方法调用之前设置,当主线程执行完毕时(包括主线程下的所有子线程),守护线程直接终止。

import threading
import time

def music():
    print('begin to listen %s' % time.ctime())
    time.sleep(3)
    print('stop to listen %s' % time.ctime())

def game():
    print('begin to play %s' % time.ctime())
    time.sleep(5)
    print('stop to play %s' % time.ctime())

if __name__ == '__main__':
    t1 = threading.Thread(target=music)
    t1.start()

    t2 = threading.Thread(target=game)
    t2.setDaemon(True)
    t2.start()


    print('ending')

全局解释器锁(GIL)

无论你启多少个线程,你有多少个cpu, Python在执行的时候会淡定的在同一时刻只允许一个线程运行,对于计算密集性任务python多线程不能提高效率,但是对于IO密集型任务多线程可以提高效率。

同步锁

加了同步锁的部分相当于串行执行,要等这部分代码执行完成后才执行其它线程。在同一时间只能有一个线程拿到同一把锁

import threading
import time

def f():
    global num

    lock.acquire()
    tmp = num
    time.sleep(0.1)
    num = tmp - 1
    lock.release()


num=100
lock = threading.Lock()

l = []
for _ in range(100):
    t = threading.Thread(target=f)
    t.start()
    l.append(t)

for t in l:
    t.join()
    
print(num)

死锁

在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁,因为系统判断这部分资源都正在使用,所有这两个线程在无外力作用下将一直等待下去。下面是一个死锁的例子:

import threading,time

class myThread(threading.Thread):
    def doA(self):
        lockA.acquire()
        print(self.name,"gotlockA",time.ctime())
        time.sleep(3)
        lockB.acquire()
        print(self.name,"gotlockB",time.ctime())
        lockB.release()
        lockA.release()

    def doB(self):
        lockB.acquire()
        print(self.name,"gotlockB",time.ctime())
        time.sleep(2)
        lockA.acquire()
        print(self.name,"gotlockA",time.ctime())
        lockA.release()
        lockB.release()

    def run(self):
        self.doA()
        self.doB()
if __name__=="__main__":

    lockA=threading.Lock()
    lockB=threading.Lock()
    threads=[]
    for i in range(5):
        threads.append(myThread())
    for t in threads:
        t.start()
    for t in threads:
        t.join()#等待线程结束,后面再讲。

递归锁

同一个线程可以拿同一把递归锁多次,没拿一次这把锁的计数器加一,当这把锁的计数器不为0时,其它线程不能拿到这把锁。

import threading,time

class myThread(threading.Thread):
    def doA(self):
        lock.acquire()
        print(self.name,"gotlockA",time.ctime())
        time.sleep(3)
        lock.acquire()
        print(self.name,"gotlockB",time.ctime())
        lock.release()
        lock.release()

    def doB(self):
        lock.acquire()
        print(self.name,"gotlockB",time.ctime())
        time.sleep(2)
        lock.acquire()
        print(self.name,"gotlockA",time.ctime())
        lock.release()
        lock.release()

    def run(self):
        self.doA()
        self.doB()
if __name__=="__main__":

    lock=threading.RLock()
    threads=[]
    for i in range(5):
        threads.append(myThread())
    for t in threads:
        t.start()
    for t in threads:
        t.join()#等待线程结束,后面再讲。

 

ThreadLocal

import threading
    
# 创建全局ThreadLocal对象:
local_school = threading.local()

def process_student():
    # 获取当前线程关联的student:
    std = local_school.student
    print('Hello, %s (in %s)' % (std, threading.current_thread().name))

def process_thread(name):
    # 绑定ThreadLocal的student:
    local_school.student = name
    process_student()

t1 = threading.Thread(target= process_thread, args=('Alice',), name='Thread-A')
t2 = threading.Thread(target= process_thread, args=('Bob',), name='Thread-B')
t1.start()
t2.start()
t1.join()
t2.join()

全局变量local_school就是一个ThreadLocal对象,每个Thread对它都可以读写student属性,但互不影响。你可以把local_school看成全局变量,但每个属性如local_school.student都是线程的局部变量,可以任意读写而互不干扰,也不用管理锁的问题,ThreadLocal内部会处理。

可以理解为全局变量local_school是一个dict,不但可以用local_school.student,还可以绑定其他变量,如local_school.teacher等等。

 

参考博客

https://www.cnblogs.com/yuanchenqi/articles/6248025.html

 

posted @ 2019-06-13 23:50  AI_Engineer  阅读(149)  评论(0)    收藏  举报