← 返回首页
Python3基础教程(四十七)
发表时间:2022-04-14 17:38:58
多线程

1.多线程

Python3中使用_thread模块或者threading模块实现多线程,threading模块相较于_thread模块对线程的操作更加的丰富,而且threading模块本身也是相当于对thread模块的进一步封装而成,thread模块有的功能threading模块也都有,所以涉及到多线程的操作,推荐使用threading模块。

实例:

# -*- coding: utf-8 -*-
# @Time : 2022/4/14 17:42
# @File : threaddemo.py
# @Software : PyCharm

import threading
from time import sleep


# 定义一个测试函数
def test(i):
    print('test', i)
    sleep(1)
    print('test', i)
    sleep(1)


if __name__ == '__main__':
    # 这里有个关键的地方是target的内容是要执行的函数名,不是函数,就是说不要把后面的括号还有参数直接写进来,参数用args来传递
    t1 = threading.Thread(target=test, args=('线程1',))
    # 再加入一个进程,当然对象也可以是其他你想要的函数
    t2 = threading.Thread(target=test, args=('线程2',))
    t1.start()  # 启动Thread对象
    t2.start()

运行结果:

test 线程1
test 线程2
test 线程2
test 线程1

2.线程同步 多线程和多进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改,因此,线程之间共享数据最大的危险在于多个线程同时改一个变量,造成数据的不一致。

实例:

import threading

cur = 0

def add():
    global cur
    for i in range(1000000):
        cur += 1

def desc():
    global cur
    for i in range(1000000):
        cur-= 1

for i in range(1000):
    thread1 = threading.Thread(target=add)
    thread2 = threading.Thread(target=desc)

    thread1.start()
    thread2.start()

    thread1.join()
    thread2.join()

    print(cur)

以上程序因为+=和-= 操作不能保证原子性,因此运行多次也不能保证cur的结果每次都是0. 与Java类似python也可以通过锁机制,实现线程同步。创建一个锁就是通过threading.Lock()来实现的。

改写如下:

# -*- coding: utf-8 -*-
# @Time : 2022/4/17 11:34
# @File : threaddemo2.py
# @Software : PyCharm

import threading
from threading import Lock, RLock

cur = 0
lock = Lock()


def add():
    global cur
    for i in range(100000):
        lock.acquire()
        try:
            cur += 1
        finally:
            lock.release()


def desc():
    global cur
    for i in range(100000):
        lock.acquire()
        try:
            cur -= 1
        finally:
            lock.release()


for i in range(1000):
    thread1 = threading.Thread(target=add)
    thread2 = threading.Thread(target=desc)

    thread1.start()
    thread2.start()

    thread1.join()
    thread2.join()

    print(cur)

Lock也有一些缺点: