线程

2020-04-18  本文已影响0人  木叶苍蓝

python的thread模块是比较底层的模块,python的threading模块是对thread做了一些包装,可以更加方便的使用。

1、使用threading模块
多线程执行
#coding=utf-8
import time

def sey_sorry():
    print("亲爱的,我错了,我能吃饭吗?")
    time.sleep(1)

if __name__ == "__main__":
    for i in range(5):
        t = threaeding.Thread(target=say_sorry)
        t.start()
多线程执行多个函数
#coding=utf-8
import time
import threading

def sing():
    for i in range(5):
        print("-------唱歌--------")
        time.sleep(1)

def dance():
    for i in range(5):
        print("--------跳舞---------")
        time.sleep(1)

def main():
    t1 = threading.Thread(target=sing)
    t2 = threading.Thread(target=dance)
    t1.start()
    t2.start()

if __name__ == "__main__":
    main()
查看线程数量
#coding=utf-8
import time
import threading

def sing()
    for i in range(5):
        print("正在唱歌...")
        time.sleep(1)

def dance():
    for i in range(5):
        print("正在跳舞...")
        time.sleep(1)

if __name__ == "__main__":
    print("------开始-----: %s"%(time.ctime(),))
    t1 = threading.Thread(target=sing)
    t2 = threading.Thread(target=dance)
    t1.start()
    t2.start()
    
    while True:
        length = len(threading.enumerate())
        print("当前运行线程数量: %s"%(length,))
        if length <= 1:
            break
        time.sleep(0.5)
线程执行代码的封装

通过使用threading模块能完成多任务的程序开发,为了让每个线程的封装性更完美,所以使用threading模块时,往往会定义一个新的子类class,只要继承threading.Thread就可以了,然后重写run方法。

#coding:=utf-8
import time
import threading

class MyThread(threading.Thread):
    def run(self):
        for i in range(3):
            time.sleep(1)
            msg = "I'm "+self.name+"@" +str(i)
            print(msg)
        self.login()
        self.register()
    def login(self):
        pass
    def register(self):
        pass
if __name__ == "__main__":
    t = MyThread()
    t.start()
多线程-共享全局变量
#coding=utf-8
import time
from threading import Thread

g_num = 100

def work1():
    global g_num
    for i in range(3):
        g_num += 1
    print("----in work1, g_num is %d-----"%(g_num,))

def work2():
    global g_num
    print("---in work2, g_num is %d-----"%(g_num,))

print("-----线程创建之前g_num is %d----"%(g_num,))
t1= Threaed(target=work1)
t1.start()
time.sleep(1)
t2 = Thread(target=work2)
t2.satrt()
多线程传参
#coding=utf-8
import ime
import threading

def test1(temp):
    temp.append(33)
    print("----in test1 temp = %s----"%(str(temp),))
def test2(temp):
    print("---in test2 temp = %s----"%(str(temp),))

g_nums = [11, 22]

def main():
    # target 指定要执行的线程
    # args 指定函数传递参数
    t1 = threaeding.Thread(target=test1, args=(g_nums,))
    t2 = threaeding.Thread(target=test2, args=(g_nums,))
    t1.start()
    time.slee(1)
    t2.start()
    time.sleep(1)
    print("----in main Thread g_nums = %s----"%(g_nums,))
if __nam__ == "__main__":
    main()
多线程-共享全局变量问题

假如两个线程t1和t2都要对全局变量g_num=0进行加1运算,t1和t2都各对g_num加10次,g_num的最终结果应该是20。
但是由于是多线程同时操作,有可能出现下面情况:

  1. 在g_num=0时,t1取得g_num=0。此时系统把t1调度为'sleeping'状态,把t2调度为'runing'状态。t2也获得g_num=0。
  2. 然后t2对得到的g_num进行加1并赋值给g_num,使得g_num=1。
  3. 然后系统有把t2调度为'sleeping',把t1转为'runing',此时t1又把之前得到的g_num=0进行加1赋值给g_num。
  4. 虽然t1和t2都对g_num加1,但是g_num最后的结果还是1。
    这里就要加互斥锁来解决这个问题
# 创建锁
mutex = threading.Lock()
# 加锁
mutex.acquire()
# 解锁
mutex.release()

注意:

#coding=utf-8
# 使用互斥锁完成2个线程对同一个全局变量各加100万次
import time
import threading

g_num = 0

def test1(num):
    global g_num
    for i in range(num):
        mutex.acquire() # 上锁
        g_num += 1
       mutex.release() # 解锁
    print("----test1---g_num=%d"%(g_num,))

def test2(num):
    global g_num
    for i in range(num):
        mutex.acquire() # 上锁
        g_num += 1
        mutex.release() # 解锁
    print("----test2---g_num=%d"%(g_num,))

# 创建一个互斥锁
# 默认是未上锁状态
mutex = threading.Lock()
def main():
    t1 = threading.Thread(target=test1, args=(1000000, ))
    t2 = threading.Thread(target=test2, args=(1000000, ))
  
    t1.start()
    t2.start()

    # 等待上面2个线程执行完毕...
    time.sleep(2)
    print("---in main Thread g_num = %d----"%(g_num,))

if __nam__ == "__main__":
    main()
死锁

在线程间共享多个资源的时候,如果两个线程分别占有一部分资源并且同时等待对方的资源,就会造成死锁。
尽管死锁很少发生,一旦发生就会造成应用的停止响应。

#coding=utf-8
import time
import threaeding

class MyThreaed(threading.Thread):
    def run(self):
        # 对mutexA上锁
        mutexA.acquire()
        # mutexA上锁后,延迟1秒,等待另一个线程对mutexB上锁
        print(self.name + "----do 1 -- up ---")
         time.sleep(1)

        # 此时会阻塞,因为这个mutexB已经被另外一个线程抢先上锁了
        mutexB.acquire()
        print(self.name+"----do1---down----")
        mutexB.release()

        # mutexA解锁
        mutexA.release()

class MyThread2(threading.Thread):
    def run(self):
        # 对 mutexB上锁
        mutexB.acquire()

        # mutexB上锁后,延迟1秒,等待另外线程把mutexA上锁
        print(self.name+"------do2-----up----")
        time.sleep(1)

        # 此时会阻塞,因为这个mutexA已经被另外线程上锁了
        mutexA.acquirt()
        print(self,name+"----do2------down------")
        mutexA.release()

        # mutexB解锁
        mutexB.release()

mutexA = threading.Lock()
mutexB = threading.Lock()

if __name__ == "__main__": 
    t1 = MyThread1()
    t2 = MyThread2()

    t1.start()
    t2.start()
上一篇下一篇

猜你喜欢

热点阅读