多进程多线程练习2

本文深入探讨Python多线程中的互斥锁(Lock)使用,通过示例解释如何确保线程安全。在多线程环境下,由于资源共享和随机调度可能导致全局变量异常。使用Lock能保证在同一时刻只有一个线程访问资源,防止数据不一致问题。
摘要由CSDN通过智能技术生成

多线程threading详解

1
import time
from threading import Thread,current_thread

def demo():
    print(f'子线程开始,线程名字:{current_thread().name}')
    time.sleep(2)
    print(f'子线程结束,线程名字:{current_thread().name}')

if __name__ == '__main__':
    print('主线程开始...')
    threads = [Thread(target=demo) for _ in range(3)]
    for t in threads:
        t.start()
    for t in threads:
        t.join()
    print('主线程结束...')

2

import time
from threading import Thread,current_thread

def demo():
    print(f'子线程开始,线程名字:{current_thread().name}')
    time.sleep(2)
    print(f'子线程结束,线程名字:{current_thread().name}')

if __name__ == '__main__':
    print('主线程开始...')
    threads = [Thread(target=demo) for _ in range(3)]
    n = 0
    for t in threads:
        n += 1
        if n == 1:
            t.setDaemon(True)
        t.start()
    print('主线程结束...')

3

通过daemon参数设置守护线程,daemon默认是None

import time
from threading import Thread,current_thread

def demo():
    print(f'子线程开始,线程名字:{current_thread().name}')
    time.sleep(2)
    print(f'子线程结束,线程名字:{current_thread().name}')

if __name__ == '__main__':
    print('主线程开始...')
    threads = [Thread(target=demo,daemon=True) for _ in range(3)]
    for t in threads:
        t.start()
    print('主线程结束...')

4

 如果子线程同时存在守护线程和非守护线程, 结果同setDaemon

import time
from threading import Thread,current_thread
def demo():
    print(f'子线程开始,线程名字:{current_thread().name}')
    time.sleep(2)
    print(f'子线程结束,线程名字:{current_thread().name}')

if __name__ == '__main__':
    print('主线程开始...')
    threads1 = Thread(target=demo,daemon=True)
    threads2 = Thread(target=demo)
    threads1.start()
    threads2.start()
    print('主线程结束...')

5

互斥锁(Lock),同一时刻仅能有一个访问者对其进行访问.

先看一个例子,假设有一个数字,实始是0,一个线程做加法,每次加1,加一百万次,同时,一个线程做减法,每次减1,减一百万次,做完后这个数字应该是0,结果却不一定

from threading import Thread
NUM = 0
def add():
    global NUM
    for i in range(1000000):
        NUM += 1
def sub():
    global NUM
    for i in range(1000000):
        NUM -= 1
if __name__ == '__main__':
    threads_add = Thread(target=add)
    threads_sub = Thread(target=sub)
    threads_add.start()
    threads_sub.start()
    threads_add.join()
    threads_sub.join()
    print(f'最终账户余额:{NUM}')

6

在同一个进程中的多线程是共享资源的,即共享全局变量,线程之间也是进行随机调度,每次做加、减时,取到的NUM是不定的,随机的,所以会导致结果出现异常,此时需要引入锁,来保证线程安全。

锁的意思是,在同一时间内,只有一个线程可以操作全局变量,即A取到NUM时,B会处于等待状态,当A交出NUM时,B才能取到NUM。

from threading import Thread,Lock
NUM = 0
def add(lock):
    global NUM
    for i in range(1000000):
        lock.acquire()
        NUM += 1
        lock.release()
def sub(lock):
    global NUM
    for i in range(1000000):
        lock.acquire()
        NUM -= 1
        lock.release()
if __name__ == '__main__':
    lock = Lock()
    threads_add = Thread(target=add,args=(lock,))
    threads_sub = Thread(target=sub,args=(lock,))
    threads_add.start()
    threads_sub.start()
    threads_add.join()
    threads_sub.join()
    print(f'最终账户余额:{NUM}')
7
支持使用with语句来实现加锁、解锁。
from threading import Thread,Lock
NUM = 0
def add(lock):
    global NUM
    with lock:
        for i in range(1000000):
            NUM += 1
def sub(lock):
    global NUM
    with lock:
        for i in range(1000000):
            NUM -= 1
if __name__ == '__main__':
    lock = Lock()
    threads_add = Thread(target=add,args=(lock, ))
    threads_sub = Thread(target=sub,args=(lock, ))
    threads_add.start()
    threads_sub.start()
    threads_add.join()
    threads_sub.join()
    print(f'最终账户余额:{NUM}')

参考

(100条消息) python多线程threading详解(二)_Neil.chen的博客-CSDN博客

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值