多线程

__thread模块

基础知识 开启一个新线程

_thread.start_new_thread(function, args[, kwargs]) 

例如

import _thread,time
def child(tid):
    print('Hello from thread', tid)
def parent():
    i = 0
    _thread.start_new_thread(child, (i,))
    time.sleep(3)
    print('hhe')
if __name__ == '__main__':
    parent()
>>>

Hello from thread 0
hhe  #(3s之后)

###
本例中载入_thread模块和创建线程并调用。
_thread.start_new_thread调用本身立即返回一个没有用的值,它派生出来的线程在其运行函数返回后安静的退出。用_thread模块时,大多数系统平台上整个程序退出时随之退出。上例中如果把time.sleep(3)的代码注释,则新线程的输出可能不成功。主线程就结束了,分线程也会随之结束
import \_thread, time
def action(i):                                       
    print(i ** 32)
class Power:
    def __init__(self, i):
        self.i = i
    def action(self):                               
        print(self.i ** 32)

_thread.start_new_thread(action, (2,))  #绑定简单函数             
_thread.start_new_thread((lambda: action(2)), ())   #绑定lambda表达式
obj = Power(2)
_thread.start_new_thread(obj.action, ())     #绑定方法对象        
time.sleep(2)
print('Main thread exiting.')       
###
在线程中对实例对象的状态做出任何改变,对于所有其他线程都是可见的           

同时运行多个线程

import _thread as thread, time
def counter(myId, count):                        # 线程中运行的程序
    for i in range(count):
        time.sleep(1)                            # 模拟耗时操作
        print('[%s] => %s' % (myId, i))

for i in range(5):                               # 开启5个线程
    thread.start_new_thread(counter, (i, 5))     # 每个线程中循环5次
time.sleep(6)
print('Main thread exiting.') 

线程所的概念
避免多个线程同时争夺同意资源而必须采用线程锁。

基础知识

mutex = _thread.allocate_lock()  创建锁

mutex.acquire()使用锁
.....操作要处理的对象
mutext.release()  释放锁

示例代码

import \_thread as thread, time

def counter(myId, count):                        
    for i in range(count):
        time.sleep(1)                            
        mutex.acquire()                                 #用锁
        print('[%s] => %s' % (myId, i))         
        mutex.release()                                  #解锁

mutex = thread.allocate_lock()                   # 创建一个全局锁
for i in range(5):                              
    thread.start_new_thread(counter, (i, 5))    
time.sleep(6)
print('Main thread exiting.')  

可以根据线程锁的状态来判断某个线程有没有完成耗时操作

import _thread as thread
stdoutmutex = thread.allocate_lock()
exitmutexes = [thread.allocate_lock() for i in range(10)]
#exitmutexes = [False]*10
def counter(myId, count):
    for i in range(count):
        stdoutmutex.acquire()
        print('[%s] => %s' % (myId, i))
        stdoutmutex.release()
    exitmutexes[myId].acquire()    # 标记myId线程完成任务 
    #exitmutexes[myId] = True

for i in range(10):
    thread.start_new_thread(counter, (i, 100))
for mutex in exitmutexes:                      #实时检测状态锁的状态。一旦全部锁住表示所有线程都完成任务。则循环完成
    while not mutex.locked(): pass
#while False in exitmutexes:pass 
print('Main thread exiting.')

threading

threading模块在内部使用_thread模块来实现代表线程的对象以及常用同步化工具的功能

import threading

class Mythread(threading.Thread):             # 继承Thread的子类
    def __init__(self, myId, count, mutex):
        self.myId  = myId
        self.count = count                     
        self.mutex = mutex                     # 传递来的线程锁
        threading.Thread.__init__(self)
    def run(self):                                   # 真正线程做的工作
        for i in range(self.count):            # 同步化 with语句线程锁
            with self.mutex:
                print('[%s] => %s' % (self.myId, i))

stdoutmutex = threading.Lock()                 #线程锁
threads = []
for i in range(10):
    thread = Mythread(i, 100, stdoutmutex)    
    thread.start()                             # 开始运行新的线程
    threads.append(thread)
for thread in threads:
    thread.join()                              # 等待线程结束 join
print('Main thread exiting.')

threading模块里的线程用Thread对象实现,通过提供定义线程的run方法来进行定制Python类Mythread,当我们创建一个Mythread类实例并调用其start方法时,run方法将在新的线程中执行。
Thread.join()方法可等待线程退出,采用这个方法避免主线程在子线程之前退出。

其他编程方法 可以直接利用Thread的默认run方法直接调用传给构造器的target参数的可调用对象aciton,args参数为传递给action的参数

threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)

import threading
def action(i):print(i**32)
thread = threading.Thread(target=action,arg=(2,))
thread.start()  #执行action

queue模块
queue模块提供一个标准的队列数据结构---一个先进先出的Python对象列表。队列对象自动有线程锁获取和释放操作控制,在任意给定时间只有一个线程能够修改队列

numconsumers = 2                
numproducers = 4                 
nummessages  = 4                
import _thread as thread, queue, time
safeprint = thread.allocate_lock()   
dataQueue = queue.Queue()             # 共享全局变量,没有限制大小 可以传参限制大小
def producer(idnum, dataqueue):
    for msgnum in range(nummessages):
        time.sleep(idnum)
        dataqueue.put('[producer id=%d, count=%d]' % (idnum, msgnum))        #放入队列

def consumer(idnum, dataqueue):
    while True:
        time.sleep(0.1)
        try:
            data = dataqueue.get(block=False)       #从队列里取值,如果队列为空者引发异常
        except queue.Empty:
            pass
        else:
            with safeprint:        #线程锁
                print('consumer', idnum, 'got =>', data)

if __name__ == '__main__':
    for i in range(numconsumers):
        thread.start_new_thread(consumer, (i, dataQueue))
    for i in range(numproducers):
        thread.start_new_thread(producer, (i, dataQueue))
    time.sleep(((numproducers-1) * nummessages) + 1)  #保证主线程最后退出
    print('Main thread exit.')
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351

推荐阅读更多精彩内容