Python 多线程
来源:互联网 发布:淘宝店铺标志图片大全 编辑:程序博客网 时间:2024/04/29 23:50
网上的一些关于python 多线程的好的总结,总结一下转了过来。
从Python2.4开始包含的较新的threading模块,为线程提供了更多强大、高级的支持。
threading模块包含了thread模块中所有的方法,并提供一些其余的方法:- threading.activeCount():返回激活的线程对象的数目
- theading.currentThread():返回调用者的线程控制中线程对象的数目
- threading.enumerate(): 返回当前活动的线程对象列表
- run():线程的入口点
- start():调用run方法启动线程
- join(time):等待线程结束
- isAlive():检查一个线程是否仍旧在执行
- getName():返回线程的名字
- setName():设置一个线程的名字
使用Threading模块创建线程:
要使用threading模块实现一个新线程,你得先如下做:- 定义Thread类的一个子类。
- 重写__init__(self,[,args])方法以增加额外的参数
- 然后,重写run(self[,args])方法以实现线程启动后要做的事情
例子:
- #!/usr/bin/python
- import threading
- import time
- exitFlag = 0
- class myThread (threading.Thread):
- def __init__(self, threadID, name, counter):
- threading.Thread.__init__(self)
- self.threadID = threadID
- self.name = name
- self.counter = counter
- def run(self):
- print "Starting " + self.name
- print_time(self.name, self.counter, 5)
- print "Exiting " + self.name
- def print_time(threadName, delay, counter):
- while counter:
- if exitFlag:
- thread.exit()
- time.sleep(delay)
- print "%s: %s" % (threadName, time.ctime(time.time()))
- counter -= 1
- # Create new threads
- thread1 = myThread(1, "Thread-1", 1)
- thread2 = myThread(2, "Thread-2", 2)
- # Start new Threads
- thread1.start()
- thread2.start()
- print "Exiting Main Thread"
#!/usr/bin/pythonimport threadingimport timeexitFlag = 0class myThread (threading.Thread): def __init__(self, threadID, name, counter): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.counter = counter def run(self): print "Starting " + self.name print_time(self.name, self.counter, 5) print "Exiting " + self.namedef print_time(threadName, delay, counter): while counter: if exitFlag: thread.exit() time.sleep(delay) print "%s: %s" % (threadName, time.ctime(time.time())) counter -= 1# Create new threadsthread1 = myThread(1, "Thread-1", 1)thread2 = myThread(2, "Thread-2", 2)# Start new Threadsthread1.start()thread2.start()print "Exiting Main Thread"
上述代码执行后,它会产出如下结果:
Starting Thread-1
Starting Thread-2
Exiting Main Thread
Thread-1: Thu Mar 21 09:10:03 2013
Thread-1: Thu Mar 21 09:10:04 2013
Thread-2: Thu Mar 21 09:10:04 2013
Thread-1: Thu Mar 21 09:10:05 2013
Thread-1: Thu Mar 21 09:10:06 2013
Thread-2: Thu Mar 21 09:10:06 2013
Thread-1: Thu Mar 21 09:10:07 2013
Exiting Thread-1
Thread-2: Thu Mar 21 09:10:08 2013
Thread-2: Thu Mar 21 09:10:10 2013
Thread-2: Thu Mar 21 09:10:12 2013
Exiting Thread-2
互斥锁同步
上面的例子引出了多线程编程的最常见问题:数据共享。当多个线程都修改某一个共享数据的时候,需要进行同步控制。
线程同步能够保证多个线程安全访问竞争资源,最简单的同步机制是引入互斥锁。互斥锁为资源引入一个状态:锁定/非锁定。某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能更改;直到该线程释放资源,将资源的状态变成“非锁定”,其他的线程才能再次锁定该资源。互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。
threading模块中定义了Lock类,可以方便的处理锁定:
#创建锁
mutex = threading.Lock()
#锁定
mutex.acquire([timeout])
#释放
mutex.release()
其中,锁定方法acquire可以有一个超时时间的可选参数timeout。如果设定了timeout,则在超时后通过返回值可以判断是否得到了锁,从而可以进行一些其他的处理。
其实并不是给资源加锁, 而是用锁去锁定资源,你可以定义多个锁, 像下面的代码, 当你需要独占某一资源时,任何一个锁都可以锁这个资源
就好比你用不同的锁都可以把相同的一个门锁住是一个道理
- #coding: utf-8
- import threading
- import time
- counter = 0
- counter_lock = threading.Lock() #只是定义一个锁,并不是给资源加锁,你可以定义多个锁,像下两行代码,当你需要占用这个资源时,任何一个锁都可以锁这个资源
- counter_lock2 = threading.Lock()
- counter_lock3 = threading.Lock()
- #可以使用上边三个锁的任何一个来锁定资源
- class MyThread(threading.Thread):#使用类定义thread,继承threading.Thread
- def __init__(self,name):
- threading.Thread.__init__(self)
- self.name = "Thread-" + str(name)
- def run(self): #run函数必须实现
- global counter,counter_lock #多线程是共享资源的,使用全局变量
- time.sleep(1);
- if counter_lock.acquire(): #当需要独占counter资源时,必须先锁定,这个锁可以是任意的一个锁,可以使用上边定义的3个锁中的任意一个
- counter += 1
- print "I am %s, set counter:%s" % (self.name,counter)
- counter_lock.release() #使用完counter资源必须要将这个锁打开,让其他线程使用
- if __name__ == "__main__":
- for i in xrange(1,101):
- my_thread = MyThread(i)
- my_thread.start()
同步阻塞
当一个线程调用锁的acquire()方法获得锁时,锁就进入“locked”状态。每次只有一个线程可以获得锁。如果此时另一个线程试图获得这个锁,该线程就会变为“blocked”状态,称为“同步阻塞”(参见多线程的基本概念)。
直到拥有锁的线程调用锁的release()方法释放锁之后,锁进入“unlocked”状态。线程调度程序从处于同步阻塞状态的线程中选择一个来获得锁,并使得该线程进入运行(running)状态。
3. 在threading.Thread中指定目标函数作为线程处理函数
- # -*- coding: utf-8 -*-
- from threading import Thread
- def run_thread(n):
- for i in range(n):
- print i
- t1 = Thread(target=run_thread,args=(5,))#指定目标函数,传入参数,这里参数也是元组
- t1.start() #启动线程
二. threading.Thread中常用函数说明
函数名 功能run()如果采用方法2创建线程就需要重写该方法getName()获得线程的名称(方法2中有示例)setName()设置线程的名称start()启动线程join(timeout) 在join()位置等待另一线程结束后再继续运行join()后的操作,timeout是可选项,表示最大等待时间setDaemon(bool)True:当父线程结束时,子线程立即结束;False:父线程等待子线程结束后才结束。默认为FalseisDaemon()判断子线程是否和父线程一起结束,即setDaemon()设置的值isAlive() 判断线程是否在运行
以上方法中,我将对join()和setDaemon(bool)作着重介绍,示例如下:
(1)join方法:
- # -*- coding: utf-8 -*-
- import threading
- import time #导入time模块
- class Mythread(threading.Thread):
- def __init__(self,threadname):
- threading.Thread.__init__(self,name = threadname)
- def run(self):
- time.sleep(2)
- for i in range(5):
- print '%s is running····'%self.getName()
- t2 = Mythread('B')
- t2.start()
- #t2.join()
- for i in range(5):
- print 'the program is running···'
这时的程序流程是:主线程先运行完,然后等待B线程运行,所以输出结果为:
- the program is running···
- the program is running···
- the program is running···
- B is running····
- B is running····
- B is running····
如果启用t2.join() ,这时程序的运行流程是:当主线程运行到 t2.join() 时,它将等待 t2 运行完,然后再继续运行t2.join() 后的操作,呵呵,你懂了吗,所以输出结果为:
- B is running····
- B is running····
- B is running····
- the program is running···
- the program is running···
- the program is running···
(2)setDaemon方法:
- # -*- coding: utf-8 -*-
- import threading
- import time
- class myThread(threading.Thread):
- def __init__(self, threadname):
- threading.Thread.__init__(self, name=threadname)
- def run(self):
- time.sleep(5)
- print '%s is running·······done'%self.getName()
- t=myThread('son thread')
- #t.setDaemon(True)
- t.start()
- if t.isDaemon():
- print "the father thread and the son thread are done"
- else:
- print "the father thread is waiting the son thread····"
这段代码的运行流程是:主线程打印完最后一句话后,等待son thread 运行完,然后程序才结束,所以输出结果为:
- the father thread is waitting the son thread····
- son thread is running·······done
如果启用t.setDaemon(True) ,这段代码的运行流程是:当主线程打印完最后一句话后,不管 son thread 是否运行完,程序立即结束,所以输出结果为:
- the father thread and the son thread are done
- Python多线程
- Python多线程
- Python多线程
- python多线程
- python 多线程
- python多线程
- python多线程
- python 多线程
- python多线程
- Python多线程
- Python 多线程
- python多线程
- python 多线程
- {python多线程}
- Python 多线程
- Python多线程
- python 多线程
- Python 多线程
- LeetCode 199. Binary Tree Right Side View
- 函数装饰@property等
- net start sshd出现发生系统错误 1069
- 《深入理解mybatis原理》 Mybatis数据源与连接池
- GPRS/GSM智能监控系统在路灯节能上的应用
- Python 多线程
- 35美元最小电脑树莓派windows10初体验 raspberry pi 2 win10
- 取词
- poj1014 Dividing(递归,多重背包)
- <tx:method/> 有关的设置
- 三元表达式
- ServiceStack.Redis之IRedisClient<第三篇>
- 文件操作
- 身高条件影响大,八成女性不嫁比自己矮的男生