多线程介绍和多线程模块
线程的特点:
线程的生命周期
开始
运行
结束
线程的退出:
进程执行完成
线程的退出方法
python的系统推出
模块函数
start_new_thread(func, args) #(func,(name,i))
allocate_lock()
exit()
[root@133 managehosts]# vim thread01.py #!/usr/bin/env python #encoding:utf8 import thread import time def func(name , i): for n in xrange(i): print name, n time.sleep(1) thread.start_new_thread(func,('声音', 3)) #(func,(name , i)) thread.start_new_thread(func,('画面', 3)) time.sleep(3) [root@133 managehosts]# python thread01.py 声音 0 画面 0 声音 1 画面 1 声音 2 画面 2
LockType对象方法
lock= thread.allocate_lock() 生成锁对象
lock.acquire() 加锁
lock.locked() 查看锁状态
lock.release() 多线程调度释放锁,使用前线程必须已经获得锁定,否则将抛出异常
[root@133 managehosts]# vim thread01.py #!/usr/bin/env python #encoding:utf8 import thread import time def func(name , i, l): for n in xrange(i): print name, n time.sleep(1) l.release() #release解锁 lock = thread.allocate_lock() #申请一把锁 lock.acquire() #获取并使用这把锁 thread.start_new_thread(func,('声音', 5, lock)) thread.start_new_thread(func,('画面', 5, lock)) while lock.locked(): #这是主进程,lock.locked=True,执行pass,主进程一直处于锁定状态,线程执行,直到线程执行完毕,释放锁,lock.locked=False pass print lock.locked() #解锁后,值为False print "Exit main process" [root@133 managehosts]# python thread01.py 声音 画面 00 画面 1 声音 1 画面 2 声音 2 画面 3 声音 3 画面 4 声音 4 False Exit main process [root@133 managehosts]# vim thread02.py #!/usr/bin/env python import thread import time def printworld(): for i in range(5): if w_lock.acquire(): print 'world',time.ctime() h_lock.release() h_lock = thread.allocate_lock() w_lock = thread.allocate_lock() thread.start_new_thread(printworld, ()) w_lock.acquire() for i in range(5): if h_lock.acquire(): print 'hello', w_lock.release() time.sleep(1) [root@133 managehosts]# python thread02.py hello world Fri Feb 10 20:26:51 2017 hello world Fri Feb 10 20:26:51 2017 hello world Fri Feb 10 20:26:51 2017 hello world Fri Feb 10 20:26:51 2017 hello world Fri Feb 10 20:26:51 2017 [root@133 managehosts]# vim thread02.py #!/usr/bin/env python import thread import time def printworld(): for i in range(5): if w_lock.acquire(): #申请world锁,if True为真 print 'world',time.ctime() #打印world h_lock.release() #释放hello锁 h_lock = thread.allocate_lock() w_lock = thread.allocate_lock() thread.start_new_thread(printworld, ()) #开启的线程,和主进程并列执行。 w_lock.acquire() #获得world锁 for i in range(5): if h_lock.acquire(): #申请hello锁,if True为真 print 'hello', #打印hello w_lock.release() #释放world锁 while h_lock.locked(): #这是主进程,直到hello打印5次后才释放。 pass [root@133 managehosts]# python thread02.py hello world Fri Feb 10 20:29:48 2017 hello world Fri Feb 10 20:29:48 2017 hello world Fri Feb 10 20:29:48 2017 hello world Fri Feb 10 20:29:48 2017 hello world Fri Feb 10 20:29:48 2017
申请了锁之后,会执行thread.start_new_thread(func,('声音',5,lock))和thread.start_new_thread(func,('画面',5,lock))这两行代码的。
执行他们的时候,同时也会执行主进程里的while的。主进程与这两个线程是同时执行的。为了不让线程退出,所以在主进程里有while来判断锁是不是已经释放了,如果是释放了,说明线程执行完了。
使用主线程控制,线程打印hello和world
[root@133 managehosts]# vim thread03.py +22 #!/usr/bin/env python import thread import time def hello(): for i in xrange(5): h_lock.acquire() print 'hello', w_lock.release() def world(): for i in xrange(5): w_lock.acquire() print 'world',time.ctime() h_lock.release() lock.release()#释放主线程的的锁 lock = thread.allocate_lock() #为主进程申请锁 lock.acquire() #主进程获得锁 h_lock = thread.allocate_lock() #为hello线程申请一把锁 w_lock = thread.allocate_lock() #为world线程申请一把锁 w_lock.acquire() #world线程获取锁 thread.start_new_thread(hello,())#启动线程hello thread.start_new_thread(world,())#启动线程world #time.sleep(1) while lock.locked(): #当主线程的锁的状态为true时 pass #什么都不做 #hello 和 world 的两个线程是同时运行的 [root@133 managehosts]# python thread03.py hello world Tue Feb 14 14:59:11 2017 hello world Tue Feb 14 14:59:11 2017 hello world Tue Feb 14 14:59:11 2017 hello world Tue Feb 14 14:59:11 2017 hello world Tue Feb 14 14:59:11 2017
从脚本的执行顺序,hello()这个函数先执行,输出hello,
然后把world的锁释放(w_lock.release())。
world()函数获得锁,输出world,然后把hello的锁释放。
必须释放对方的锁,对方才能获得锁(h_lock.acquire()),如果对方的锁没有被释放,那么对方再想获得锁是不成功的,会一直处于阻塞状态,直到锁被释放。
hello()函数第一次获得了锁资源(h_lock.acquire()),打印了hello,接着释放了world的锁资源(w_lock.release())。
world()函数获得了锁资源(w_lock.acquire()),打印了world,接着释放了hello的锁资源(h_lock.release())。
由于hello的锁资源被释放了,hello函数里又获得了锁资源,接着第二次打印hello。
也就是说哪个函数或得了锁资源,就会打印相应的信息。
锁资源只有被释放了,下一次才能获得,即已经获得了锁资源,不能再次获得,所以在hello函数里释放world的锁资源,在world函数里才能获得锁资源。
这样反反复复,就打印了hello world。
threading
threading不需要进程的控制来控制线程
threading.Thread:类
成员方法:
start() 启动线程
run() 可以重写
join() 阻塞
getName()
setName()
isDaemon()判断线程是否随主线程一起结束
setDaemon设置线程与主线程一起结束
In [1]: import threading In [2]: help(threading.Thread) Help on class Thread in module threading: class Thread(_Verbose) | Method resolution order: | Thread | _Verbose | __builtin__.object | | Methods defined here: | | __init__(self, group=None, target=None, name=None, args=(), kwargs=None, verbose=None)
[root@133 managehosts]# vim threading01.py #!/usr/bin/env python import threading import time def func(): print 'hello',time.ctime() time.sleep(1) if __name__ == '__main__': for i in xrange(10): t = threading.Thread(target=func, args =()) t.start() print 'complete' [root@133 managehosts]# python threading01.py hello Tue Feb 14 15:42:10 2017 #瞬间打印10行 hello Tue Feb 14 15:42:10 2017 hello Tue Feb 14 15:42:10 2017 hello Tue Feb 14 15:42:10 2017 hello Tue Feb 14 15:42:10 2017 hello Tue Feb 14 15:42:10 2017 hello Tue Feb 14 15:42:10 2017 hello Tue Feb 14 15:42:10 2017 hello Tue Feb 14 15:42:10 2017 hello Tue Feb 14 15:42:10 2017 complete
如果添加t.join,则会阻塞,每秒打印一次,上一个阻塞执行完才会执行下一个
def func(): print 'hello',time.ctime() time.sleep(1) if __name__ == '__main__': for i in xrange(10): t = threading.Thread(target=func, args =()) t.start() t.join() [root@133 managehosts]# python threading01.py hello Tue Feb 14 15:42:10 2017 #每隔一秒打印一次 hello Tue Feb 14 15:42:10 2017 hello Tue Feb 14 15:42:10 2017 hello Tue Feb 14 15:42:10 2017 hello Tue Feb 14 15:42:10 2017 hello Tue Feb 14 15:42:10 2017 hello Tue Feb 14 15:42:10 2017 hello Tue Feb 14 15:42:10 2017 hello Tue Feb 14 15:42:10 2017 hello Tue Feb 14 15:42:10 2017 complete
[root@133 managehosts]# vim threading02.py #!/usr/bin/env python #encoding:utf8 import threading import time def func(name, i): for n in xrange(i): print name, n time.sleep(1) t1 = threading.Thread(target=func, args=('声音',3)) t2 = threading.Thread(target=func, args=('画面',3)) t1.start() t2.start() [root@133 managehosts]# python threading02.py 声音 0 画面 0 声音 1 画面 1 声音 2 画面 2 如果添加一个t1.join(),则会先打印t1,然后再打印t2 t1.start() t1.join() t2.start() 结果变为: [root@133 managehosts]# python threading02.py 声音 0 声音 1 声音 2 画面 0 画面 1 画面 2
t1.setDaemon(True) 设置t1线程和主进程一起退出
[root@133 managehosts]# vim threading02.py #!/usr/bin/env python #encoding:utf8 import threading import time def func(name, i): for n in xrange(i): print name, n time.sleep(1) t1 = threading.Thread(target=func, args=('声音',3)) t2 = threading.Thread(target=func, args=('画面',3)) t1.setDaemon(True) #设置t1线程和主进程一起退出 t1.start() #开启t1线程,打印一次就会退出,因为主进程已经退出 t2.setDaemon(True) t2.start() [root@133 managehosts]# python threading02.py 声音 0 画面 0
互斥锁
[root@133 managehosts]# pwd /opt/python/managehosts [root@133 managehosts]# cat threading07.py #!/usr/bin/env python import threading import time def hello(): for i in xrange(5): h_lock.acquire() print 'hello', w_lock.release() def world(): for i in xrange(5): w_lock.acquire() print 'world',time.ctime() h_lock.release() h_lock = threading.Lock() w_lock = threading.Lock() w_lock.acquire() t1 = threading.Thread(target=hello, args=()) t2 = threading.Thread(target=world, args=()) t1.start() t2.start() [root@133 managehosts]# python threading07.py hello world Wed Mar 29 11:51:59 2017 hello world Wed Mar 29 11:51:59 2017 hello world Wed Mar 29 11:51:59 2017 hello world Wed Mar 29 11:51:59 2017 hello world Wed Mar 29 11:51:59 2017
#!/usr/bin/python import thread import time def hello(): for i in xrange(5): h_lock.acquire() print 'hello', w_lock.release() def world(): for i in xrange(5): w_lock.acquire() print 'world' h_lock.release() lock.release() lock = thread.allocate_lock() lock.acquire() h_lock = thread.allocate_lock() w_lock = thread.allocate_lock() w_lock.acquire() thread.start_new_thread(hello, ()) thread.start_new_thread(world, ()) while lock.locked(): pass
程序执行开两个线程,即hello和world。
执行hello线程时,只有3步:
先申请h_lock锁,即h_lock.acquire()
然后输出hello,即print 'hello',
最后释放w_lock锁,即w_lock.release()
执行world线程时也是3步:
申请w_lock锁,即w_lock.acquire()
输出world,即print 'world'
释放h_lock锁,即h_lock.release()
线程是同时执行的,为什么hello和world会交替输出,没有先输出world?
在主线程里,申请了w_lock锁,即26行的w_lock.acquire(),所以在world()函数里的w_lock.acquire()一直
处于阻塞状态,意味着print 'world'这一行是不会执行的,直到hello()函数里把w_lock释放,即w_lock.release()
所以在每个函数里都有释放对方的锁,这样对方就把自己要输出的内容执行了。
最后world函数里的循环执行完了,释放lock这个锁,这样这个主进程也结束了。
[root@133 managehosts]# cat threading08.py #!/usr/bin/env python import threading import time class MyThread(threading.Thread): def __init__(self): threading.Thread.__init__(self) def run(self): global counter time.sleep(1) mutex.acquire() #获得锁 counter +=1 print "I am %s, set counter:%s" %(self.name,counter) mutex.release() #释放锁 if __name__ == '__main__': counter = 0 mutex = threading.Lock() #分配锁 for i in xrange(300): t = MyThread() t.start() [root@133 managehosts]# python threading08.py I am Thread-1, set counter:1 I am Thread-2, set counter:2 I am Thread-3, set counter:3 I am Thread-4, set counter:4 I am Thread-5, set counter:5 I am Thread-6, set counter:6 I am Thread-7, set counter:7 I am Thread-8, set counter:8 I am Thread-9, set counter:9 I am Thread-10, set counter:10 I am Thread-11, set counter:11 I am Thread-12, set counter:12 I am Thread-13, set counter:13 I am Thread-14, set counter:14 I am Thread-15, set counter:15 I am Thread-284, set counter:282 I am Thread-283, set counter:283 I am Thread-282, set counter:284 I am Thread-285, set counter:285 I am Thread-287, set counter:286 I am Thread-286, set counter:287 I am Thread-288, set counter:288 I am Thread-289, set counter:289 I am Thread-290, set counter:290 I am Thread-293, set counter:291 I am Thread-292, set counter:292 I am Thread-291, set counter:293 I am Thread-295, set counter:294 I am Thread-296, set counter:295 I am Thread-297, set counter:296 I am Thread-294, set counter:297 I am Thread-298, set counter:298 I am Thread-299, set counter:299 I am Thread-300, set counter:300
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。