首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python-多线程

python-多线程

作者头像
luxuantao
发布2021-02-24 11:26:03
2620
发布2021-02-24 11:26:03
举报
文章被收录于专栏:Fdu弟中弟Fdu弟中弟

python中有关多线程的操作方法。

threading库是python支持多线程编程的重要模块。

线程的创建

一种方法是直接使用threading中的Thread类创建对象。

另一种方法是继承Thread类并重写__init__()run()方法。

线程的管理

join([timeout])

阻塞当前线程,等待被调线程结束或超时后再执行当前线程,timeout单位是秒。

from threading import Thread
import time

def fun(x, y):
    for i in range(x, y):
        print(i, end=' ')
    print()
    time.sleep(10) #等待10秒

t1 = Thread(target=fun, args=(15, 20))
t1.start()
t1.join(5) #等待t1结束或等待5秒
t2 = Thread(target=fun, args=(5, 10))
t2.start()

isAlive()

测试线程是否处于运行状态。

from threading import Thread
import time

def fun():
    time.sleep(10) #等待10秒

t1 = Thread(target=fun)
print('t1:',t1.isAlive()) #False

t1.start()
print('t1:',t1.isAlive()) #True

t1.join(5) #因超时而结束
print('t1:',t1.isAlive()) #True

t1.join() #等待t1结束
print('t1:',t1.isAlive()) #False

daemon属性

如某个子线程的daemon属性为False(默认情况),主线程结束时会检测该子线程是否结束并等待它结束后再退出。若为True,则该子线程不管有没有运行玩,都会随主线程一起结束。

import threading
import time

class mythread(threading.Thread):
    def __init__(self, num, threadname):
        threading.Thread.__init__(self,name=threadname)
        self.num = num
    def run(self):        
        time.sleep(self.num)
        print(self.num)

t1 = mythread(1, 't1')
t2 = mythread(5, 't2')
t2.daemon = True
t2.setDaemon(False)
print(t1.daemon) #False
print(t2.daemon) #True
t1.start()
t2.start()

1会输出,但5不会输出。

线程的同步

RLock对象

import threading
import time

class mythread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        
    def run(self):
        global x
        lock.acquire() #获取锁,如果成功则进入临界区
        x += 1
        time.sleep(0.5)
        print(x)
        lock.release() #释放锁,退出临界区

lock = threading.RLock()
tl = [] #用来存放多个进程
x = 0
for i in range(10000):
    t = mythread()
    tl.append(t)
for i in tl:
    i.start()

如果没有这把读锁,那么x的值将会变得杂乱无章,出现“脏读”现象。

“死锁”现象:假设有两个线程和两把锁,只有两把锁都给同一个线程的时候这个线程才会运行。那么问题来了,当两个线程各自获得了其中的一把锁,这时它们都在等待另一把锁释放,这时就会出现死锁现象。

Condition对象

用经典的生产者和消费者问题演示。

import threading
from random import randint
import time

class Producer(threading.Thread):
    def __init__(self, threadname):
        threading.Thread.__init__(self,name=threadname)

    def run(self):
        global x
        while True:
            con.acquire() #获取锁
            if len(x) == 10:
                print('Producer is waiting')
                con.wait() #共享列表已有10个元素,不再生产
            else:
                print('Producer:', end=' ')
                x.append(randint(1,1000))
                print(x)
                time.sleep(1)
                con.notify() #唤醒等待条件的线程
            con.release() #释放锁

class Consumer(threading.Thread):
    def __init__(self, threadname):
        threading.Thread.__init__(self, name =threadname)

    def run(self):
        global x
        while True:
            con.acquire()
            if not x:
                print('Consumer is waiting')
                con.wait() #共享列表没东西,暂停消费
            else:
                print(x.pop(0))
                print(x)
                time.sleep(1)
                con.notify()
            con.release()

con = threading.Condition()
x = []
p = Producer('Producer')
c = Consumer('Consumer')
p.start()
c.start()
p.join()
c.join()

notify()方法是从所有等待这个对象锁的线程中随机唤醒一个。

notify_all()方法能够唤醒所有正在等待这个对象锁的线程,唤醒的线程获得锁的概率是随机的,取决于cpu调度。

notify()或者notify_alll()方法并不是真正释放锁,必须等到release方法执行完才真正释放锁。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-03-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 线程的创建
  • 线程的管理
    • join([timeout])
      • isAlive()
        • daemon属性
        • 线程的同步
          • RLock对象
            • Condition对象
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档