python线程
单线程:
import time def test1(): time.sleep(2) print("The test1 started at: %s" %time.ctime()) def test2(): time.sleep(2) print("The test2 started at: %s" %time.ctime()) test1() test2()
运行结果:
zhuh@baojp-24000649:~/pra$ python3 arg1.py The test1 started at: Thu Mar 1 08:28:07 2018 The test2 started at: Thu Mar 1 08:28:09 2018
由时间可以看出test1()和test2()按照顺序运行。
之后将代码改成多线程:
import time import threading def test1(): print("The test1 started at: %s" %time.ctime()) time.sleep(1) print("The test1 finished at: %s" %time.ctime()) def test2(): print("The test2 started at: %s" %time.ctime()) time.sleep(1) print("The test2 finished at: %s" %time.ctime()) t1 = threading.Thread(target = test1,name = "test1") t2 = threading.Thread(target = test2,name = "test2") for i in [t1,t2]: i.start() print("Current number of threads: %d" %threading.active_count()) for j in [t1,t2]: j.join() print("Finished!")
运行结果:
zhuh@baojp-24000649:~/pra$ python3 arg1.py The test1 started at: Thu Mar 1 08:54:34 2018 The test2 started at: Thu Mar 1 08:54:34 2018 Current number of threads: 3 The test1 finished at: Thu Mar 1 08:54:35 2018 The test2 finished at: Thu Mar 1 08:54:35 2018 Finished!
thread类代表可以运行一个独立的线程的活动,特定化这个活动的方法有两种,一个是给constructor传一个可调用对象,另个一个是在子类中重载Thread方法。其他在子类中的方法不允许被重载。也就是说,智能重载 _init()_ 和 run()
一旦一个线程被创建,必须通过调用start()方法来开始它的活动。这会在一个独立的线程控制中唤醒run()方法。
一旦一个线程活动开始,这个线程就被认为是 'alive'。直到run()方法结束——正常结束或者抛出不能够处理的异常,这个线程才被认为停止‘alive’。 is_alive()方达可以测试线程有没有‘alive’。
join()方法可以阻塞调用该线程的父线程直到该线程运行完成。join
(timeout=None) 当时间等于timeout且timeout不为None时,阻塞结束。
改一下代码:
t1 = threading.Thread(target = test1,name = "test1") t2 = threading.Thread(target = test2,name = "test2") for i in [t1,t2]: i.start() print("Current number of threads: %d" %threading.active_count()) for j in [t1,t2]: j.join(timeout = 1) print("%s bolck Finished!" %j.name) print("%s is alive: %s" %(j.name,j.is_alive())) time.sleep(2)
运行结果:
zhuh@baojp-24000649:~/pra$ python3 arg1.py The test1 started at: Thu Mar 1 09:28:23 2018 The test2 started at: Thu Mar 1 09:28:23 2018 Current number of threads: 3 test1 bolck Finished! test1 is alive: True test2 bolck Finished! test2 is alive: True The test1 finished at: Thu Mar 1 09:28:25 2018 The test2 finished at: Thu Mar 1 09:28:25 2018
class threading.
Thread
(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)¶
kwargs is a dictionary of keyword arguments for the target invocation. Defaults to {}
If not None
, daemon explicitly sets whether the thread is daemonic. If None
(the default), the daemonic property is inherited from the current thread.
多线程要注意资源的互斥使用,即在同一时间段某一个资源只能由一个线程来操作,比如写文件操作。threading提供了Lock Object来实现资源的互斥访问。
一个简单的lock有两种状态,“locked”和“unlocked”。lock被创建时是“unlocked”状态。他有两种基本操作,acquire() 和 release()。状态为“unlocked时,调用acquire()来改变状态,当状态为“locked”时,acquire()会被阻塞直到调用release()改变lock的状态。release()不能在lock为“unlocked”状态时调用,否则会产生“RunTimeError”。
acquire
(blocking=True, timeout=-1)¶
Acquire a lock, blocking or non-blocking.
When invoked with the blocking argument set to True
(the default), block until the lock is unlocked, then set it to locked and return True
.
When invoked with the blocking argument set to False
, do not block. If a call with blocking set to True
would block, return False
immediately; otherwise, set the lock to locked and return True
.
When invoked with the floating-point timeout argument set to a positive value, block for at most the number of seconds specified by timeoutand as long as the lock cannot be acquired. A timeout argument of -1
specifies an unbounded wait. It is forbidden to specify a timeout when blocking is false.