python 多线程

本文介绍了Python中实现多线程的两种方法:使用thread模块的start_new_thread()函数和继承threading.Thread类创建子类。并通过示例展示了如何避免主线程提前结束导致的异常。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在谈多线程之前我们先谈谈,进程和线程的关系。


一个简单的hello world程序,其实就是一个进程在运行。


那么这个进程有多少线程组成呢,答案是一。


程序的执行是顺序的,只有等到上一条语句执行完毕才到下一条执行语句。那么如果我需要程序在不断打印hello world的同时又在不断地打印good bye world呢?在没学多线程之前我们会觉得很麻烦,但是当你学了多线程时候你就发现其实很简单的一个操作。开一个线程打印hello world 一个线程打印good bye world 就可以。


接下来看看 ,怎么去实现多线程。


python 实现多线程,一般来说有两种方式:


1. 函数式:调用thread模块中的start_new_thread()函数来产生新线程

eg:

import time
import thread


def timer(id, interval):

cnt = 0

while cnt<10:

print 'Thread:(%d) cnt: (%d) Time:%s\n'%(id,cnt,time.ctime())

time.sleep(interval)

cnt += 1

thread.exit_thread()

def main():

thread.start_new_thread(timer,(1,1))

thread.start_new_thread(timer,(2,2))

if __name__ == '__main__':

main()


接下来还等什么。。。赶紧跑起。。。。可是我们会发现。。。运行时候报错。。。。
错误信息为:
Unhandled exception in thread started by


Error in sys.excepthook:


Original exception was:


这什么意思啊,我们的程序都是照着书本敲的,为什么会报该类错误?


其实很简单,我们启动程序时候是有一个主进程在运行的,新起一个子线程执行别的任务,但是当主线程已经执行完毕,子线程还没有执行完毕呢?这时候就会抛出中断异常。(这也与子线程是否是后台进程无关)


知道原因,自然就有解决办法,我们可以延长主线程存活的时间,主线程没事干怎么办?。。。等待是一个好办法。。。


解决:

def main():

thread.start_new_thread(timer,(1,1))


thread.start_new_thread(timer,(2,2))

time.sleep(20) #注意,主线程存活时间一定大于其子线程存活时间,sleep时间具体是多少,可以估量


接下来,程序跑起。。。。。没问题。。。。。。


---------------------------------------------------------------------------------------------------


2. 创建threading.Thread的子类来包装一个线程对象

import time
import threading


class Timer(threading.Thread):


def __init__(self, id, interval):

threading.Thread.__init__(self)

self.id = id

self.interval = interval

self.thread_stop = False


def run(self):

cnt = 0

while not self.thread_stop:

print 'Thread:(%d) cnt:(%d) Time:(%s)\n'%(self.id, cnt, time.ctime())

time.sleep(self.interval)

cnt += 1

def stop(self):

self.thread_stop = True

def main():


timer1 = Timer(1,1)

timer2 = Timer(2,2)

timer1.start()

timer2.start()

time.sleep(20)

timer1.stop()

timer2.stop()

if __name__ == '__main__':

main()


run方法是必须要实现的一个方法。。。。stop方法是为了控制子进程结束进程而添加的。。。


废话少说。。。程序跑起。。。。。。。。
-----------------------------------------------------------------------------------------------


就个人来说,我比较喜欢,第二种方法,自己定制线程类,还可以控制子线程的存活时间


threading.Thread 主要方法有:
1,在自己的线程类的__init__里调用threading.Thread.__init__(self, name = threadname)

Threadname为线程的名字

2, run(),通常需要重写,编写代码实现做需要的功能。

3,getName(),获得线程对象名称

4,setName(),设置线程对象名称

5,start(),启动线程

6,jion([timeout]),等待另一线程结束后再运行。

7,setDaemon(bool),设置子线程是否随主线程一起结束,必须在start()之前调用。默认为False。

8,isDaemon(),判断线程是否随主线程一起结束。

9,isAlive(),检查线程是否在运行中。

------------------------------------------------------------------------------------------------

3. 进程加锁机制:

大家都听过生产者和消费者问题吧,没听过的自己百度去,我在这里就不赘述,直入正题吧。


import threading

import random

class Consumer(threading.Thread): #消费者

def __init__(self):

threading.Thread.__init__(self)

def run(self):

global container

con.acquire()

if len(container) <= 1:

con.wait()

con.notify()

else:

while len(container)> 1:

bread = container.pop()

print 'eat a bread %d'%(bread.getId())

con.release()

def __del__(self):

print 'consumer distructor'

class Master(threading.Thread): #生产者

def __init__(self):

threading.Thread.__init__(self)

def run(self):

global container

con.acquire()

if len(container) >= 20:

con.wait()

con.notify()

else:

while len(container) < 20:

bread = Bread(random.randint(10, 100))

print 'produce a bread %d'%(bread.getId())

container.append(bread)

con.release()

def __del__(self):

print 'Master Constructor'

class Bread(): #产品

def __init__(self,id):

self.id = id

def getId(self):

return self.id

def __del__(self):

print 'Bread constructor'


container = []

con = threading.Condition()

mas = Master()

cons = Consumer()

mas.start()

cons.start()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值