Python进阶基础学习(多线程)

Python进阶学习笔记(一)

threading模块

threading.thread(target = (函数))  负责定义子线程对象

threading.enumerate()  负责查看子线程对象

测试代码如下:

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)  #子线程1
    t2 = threading.Thread(target=dance) #子线程2
    t1.start()
    t2.start()
    while True:
        print(threading.enumerate())
        if  len(threading.enumerate()) == 1:
            break
        time.sleep(1)
if __name__ == '__main__':
    main()

补充:

线程的调度是随机的,主线程如果在子线程之前GG,你们子线程也GG

threading.thread()不会创建线程,只有调用其实例.start()之后才会创建线程

通过类来创建线程

测试代码如下:

import threading
import time
class Person(threading.Thread):
    def run(self) -> None:
        for i in range(3):
            print('aaa' + self.name)
            time.sleep(1)

if __name__ == '__main__':
    p = Person()
    p.start()
    for i in range(3):
        print('bbb')
        time.sleep(1)

补充:

threading.thread是一个类,通过继承并且override run函数,即可声明进程

多线程共享全局变量

测试代码如下:

import threading
import time
num = 100
def test1():
    global num
    num += 1
    print(num)
def test2():
    print(num)
def main():
    t1 = threading.Thread(target=test1)
    t2 = threading.Thread(target=test2)
    t1.start()
    time.sleep(1)
    test2()
if __name__ == '__main__':
    main()

若创建线程是需要带参数,则是用args

测试代码如下:

num = [1,1,2,3]

def test1(args):
    args.append('hhs')
    print(args)

def main():
    t1 = threading.Thread(target=test1,args=(num,))
    t1.start()
    print(num)

if __name__ == '__main__': 
    main()

补充:args后边传的是一个元组,少了逗号会报错

多线程共享全局变量出现的问题

测试代码如下:

import threading
import time

g_num = 0
def count1(n):
    global g_num
    for i in range(n):
        g_num += 1

def count2(n):
    global g_num
    for i in range(n):
        g_num += 1

def main():
    t1 =threading.Thread(target=count1,args=(100000,))
    t2 = threading.Thread(target=count2, args=(100000,))
    t1.start()
    t2.start()
    time.sleep(2)
    print('正常num为200000,实际num为%d' % g_num)

if __name__ == '__main__':
    main()

补充:输出结果为:175586,与正常结果不相同

解析问题:

1.cpu是一句句执行的

2.若把g_num += 1解析成很多句,如果线程1只执行1-2句,第三句还没赋值回去,就调用了线程2,则会出现相加的结果不等于预期的结果

互斥锁threading.Lock()

用于解决上面共享全局变量的问题

变量名.acquire()  上锁

变量名.release()  解锁

给要执行的代码上锁,自己运行的时候别的线程无法运行

测试代码如下:

import threading
import time

num = 0
mutex = threading.Lock()
def count1(n):
    global num
    for i in range(n):
        mutex.acquire()
        num += 1
        mutex.release()

def count2(n):
    global num
    for i in range(n):
        mutex.acquire()
        num += 1
        mutex.release()

def main():
    t1 =threading.Thread(target=count1,args=(100000,))
    t2 = threading.Thread(target=count2, args=(100000,))
    t1.start()
    t2.start()
    time.sleep(2)
    print('正常num为200000,实际num为%d' % num)

if __name__ == '__main__':
    main()

  

原文地址:https://www.cnblogs.com/hhs1998/p/11772665.html