Python(线程)

线程

  • 进程相互独立,线程依赖于进程
  • 线程需要抢CPU,谁先抢到谁执行
 **Python中使用线程有两种方式:函数或者用类来包装线程对象。

1.函数式:调用thread模块中的start_new_thread()函数来产生新线程。
    thread.start_new_thread ( function, args[, kwargs] )
2.使用Threading模块创建线程,直接从threading.Thread继承,然后重写__init__方法和run方法 
   	** 

线程冲突,5个线程同时抢夺num的资源,导致最后结果错误

import _thread
num = 0
def add():
    for _ in range(1000000):
        global num
        num += 1
    print(num)
for i in range(5):
    _thread.start_new_thread(add,())
while True:  # 防止主线程不死
    pass

基于类实现线程

import threading
import win32api
class Mythread(threading.Thread):   # 继承threading.Thread类
    def run(self):  # 重写threading.Thread类中的run函数
        win32api.MessageBox(0,"hello",'joker',0)
for i in range(5):  # 同时创建5个线程
    t = Mythread()  # 初始化
    t.start()  # 开启
while True:
    pass

类线程的顺序风格

import threading
import win32api
class Mythread(threading.Thread):   # 继承threading.Thread类
    def run(self):  # 定义函数
        win32api.MessageBox(0,"hello",'joker',0)
for i in range(5):
    t = Mythread()  # 初始化
    t.start()  # 开启
    t.join()
print("game over")

  • start是启动线程,join是阻塞当前线程,即使得在当前线程结束时,不会退出。

类线程的乱序风格

import threading
import win32api
class Mythread(threading.Thread):  # 继承threading.Thread类
    def __init__(self, num):
        threading.Thread.__init__(self)  # 父类初始化
        self.num = num
    def run(self):  # 定义函数
        win32api.MessageBox(0, "hello" + str(self.num), 'joker', 0)
        print(self.getName())  # 获取线程名
Mythd = []
for i in range(5):
    t = Mythread(i)  # 初始化
    print(i)
    t.start()  # 开启
    Mythd.append(t)  # 将乱序线程(同时抢夺run这个函数)加入列表
for j in Mythd:
    j.join()  # 这里主线程同时等待所有线程都执行完毕,才执行“game over”
print("game over")

基于类解决线程冲突

import threading
num = 0
mutex = threading.Lock()  # 创建一个锁,threading.Lock()是一个类
class Myhtread(threading.Thread):
    def run(self):
        global num
        if mutex.acquire(1):  # 如果锁成功,那么线程继续干活,如果锁失败,下面的线程一直等待锁成功,1,代表独占
            for i in range(1000):  # 数字小的时候还是不会产生线程冲突的
                num += 1
            mutex.release()  # 释放锁,一定切记
        print(num)
mythread = []
for i in range(5):
    t = Myhtread()
    t.start()
    mythread.append(t)
for thread in mythread:
    thread.join()  # 或者直接将thread.join()加入for i in range(5),也能解决线程冲突,但是貌似就变成单线程了
print("game over")

用两个线程随机获取100个验证码,写入本地文件

import threading
import random
class Mythread (threading.Thread):
    def __init__(self,lock):
        threading.Thread.__init__(self)
        self.lock = lock
        self.list_ = []
    def run(self):
        for i in range(50):
            num = random.randrange(1000,9999)
            print(num)
            self.list_.append(num)
        with self.lock:
            self.write(self.list_)
    def write(self,res):
        b = [str(x)+'\n' for x in res]
        b = ''.join(b)
        with open('./res.txt',mode = 'a')as file:
            file.write(str(res)+'\n')
if __name__ == "__main__":
    mythread = []
    lock = threading.Lock()
    for i in range(2):
        t = Mythread(lock)
        t.start()
        mythread.append(t)

    for t in mythread:
        t.join()
    print("Over")

Rlock避免单线程死锁

import threading
num = 0
mutext = threading.RLock()  
class Mythreading(threading.Thread):
    def run(self):
        global num
        if mutext.acquire(1):
            num += 1
            print(self.name, num)
            if mutext.acquire(1):
                num += 1000
                mutext.release()
            mutext.release()
for i in range(5):  # 开启5个进程
    t = Mythreading()
    t.start()

threading.Semaphore(2) # 限制最大线程数为2个
threading.Barrier(2) #凑出线程数量,也就是说一定要至少凑成两个才能执行

线程通信

import threading
import time
def deco2(times):
    def deco(func):
        def warp(*args,**kwargs):
            e = args[0]
            time.sleep(times)
            e.set()
            return func(*args,**kwargs)
        return warp
    return deco    
@deco2(5)
def B(e):
    e.wait()
    print("hello")

if __name__ == "__main__":
    e = threading.Event()
    t = threading.Thread(target=B,args=(e,))
    t.start()
    t.join()
   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值