Python多线程:thread、threading、queue

一、名字解释

        Python虚拟机:也叫解释器主循环,控制Python代码的执行。

        多线程:类似单CPU系统中运行多个进程。 任意时刻,只能有一个线程在解释器中运行。

        全局解释器锁(GIL):保证同一个时刻只有一个线程在运行。

二、thread

#!/usr/bin/env python

#import thread
from time import sleep, ctime

def loop0():
        print "start loop 0 at:", ctime()
        sleep(4)
        print "end loop 0 at:", ctime()

def loop1():
        print "start loop 1 at:", ctime()
        sleep(2)
        print "end loop 1 at:",ctime()

def main():
        print "starting at:", ctime()
        loop0()
        loop1()
        #thread.start_new_thread(loop0,())
        #thread.start_new_thread(loop1,())
        #sleep(6)
        print "ending at:", ctime();

if __name__ == "__main__":
        main()

        没有thread:共耗时4+2=6秒

Python多线程:thread、threading、queue_第1张图片

        有thread,无锁:并发执行,共耗时4秒,需要主线程中手动sleep

Python多线程:thread、threading、queue_第2张图片

#!/usr/bin/env python

import thread
from time import sleep, ctime

secs = [4,2]

def loop(nloop, nsec, lock):
        print "start loop ", nloop," at:", ctime()
        sleep(nsec)
        print "end loop ", nloop, " at:", ctime()
        lock.release()

def main():
        print "starting at:", ctime()
        nsecs = range(len(secs))
        locks = []
        for i in nsecs:
                lock = thread.allocate_lock()
                lock.acquire()
                locks.append(lock)

        for i in nsecs:
                thread.start_new_thread(loop, (i, secs[i], locks[i]))

        for i in nsecs:
                while locks[i].locked(): pass
        print "ending at:", ctime();

if __name__ == "__main__":
        main()

        有thread,有锁:共耗时4秒,主线程无需等待

Python多线程:thread、threading、queue_第3张图片

三、threading

3种创建线程方法

        1. 创建一个Thread的实例,传给它一个函数

        2. 创建一个Thread的实例,传给它一个可调用的类对象

        3. 从Thread派生出一个子类,创建一个这个子类的实例

#!/usr/bin/env python

import threading
from time import sleep, ctime

secs = [4,2]

#class ThreadFunc(object):
#       def __init__(self, func, args, name=''):
#               self.name = name
#               self.func = func
#               self.args = args
#
#       def __call__(self):
#               apply(self.func, self.args)

def loop(nloop, nsec):
        print "start loop ", nloop, " at:", ctime()
        sleep(nsec)
        print "end loop ", nloop," at:", ctime()

def main():
        print "starting at:", ctime()
        nsecs = range(len(secs))
        threads = []
        for i in nsecs:
                #t = threading.Thread(target=ThreadFunc(loop, (i, secs[i]), loop.__name__))
                t = threading.Thread(target=loop,args=(i,secs[i]))
                threads.append(t)

        for i in nsecs:
                threads[i].start()

        for i in nsecs:
                threads[i].join()
        print "ending at:", ctime();

if __name__ == "__main__":
        main()

上述代码是2种创建线程方法:执行结果一样,都是耗时4秒,主线程无需等待

Python多线程:thread、threading、queue_第4张图片      Python多线程:thread、threading、queue_第5张图片

四、threading.Lock

        import threading


        g_lock = threading.Lock()

        g_lock.acquire()

        g_lock.release()

import threading

g_tickets = 100
g_lock = threading.Lock()

def loop1():
        global g_tickets
        global g_lock

        while True:
                g_lock.acquire()
                if g_tickets > 0:
                        print("thread 1 sell tickets: %d" % (g_tickets))
                        g_tickets = g_tickets - 1
                else:
                        g_lock.release()
                        break
                g_lock.release()

def loop2():
        global g_tickets
        global g_lock

        while True:
                g_lock.acquire()
                if g_tickets > 0:
                        print("thread 2 sell tickets: %d" % (g_tickets))
                        g_tickets = g_tickets - 1
                else:
                        g_lock.release()
                        break
                g_lock.release()

def main():
        t1 = threading.Thread(target=loop1, args=());
        t2 = threading.Thread(target=loop2, args=())

        t1.start()
        t2.start()

        t1.join()
        t2.join()

if __name__ == "__main__":
        main()

五、尽量使用threading,避免使用thread

        1. threading模块更为先进,对线程支持更完善,使用thread模块可能会与threading出现冲突。

        2. thread模块同步原语少(只有一个),threading模块有很多。

        3. thread,当主线程结束时,所有线程都被强制结束掉;threading模块能确保重要的子线程退出口进程再退出。

六、Queue

        import Queue


        queue = Queue.Queue(maxsize=10)

        queue.put(num)

        num = queue.get()

        queue.qsize()

import threading
import Queue
import random
import time

queue = Queue.Queue(maxsize=10)

def loop1():
        while True:
                if queue.qsize() < 10:
                        num = random.randint(1, 100)
                        print("produce num: %d" % (num))
                        queue.put(num)

                time.sleep(random.randint(1,3))

def loop2():
        while True:
                if queue.qsize > 0:
                        num = queue.get()
                        print("consumer num: %d" % (num))

                time.sleep(random.randint(1,3))

def main():
        t1 = threading.Thread(target=loop1, args=())
        t2 = threading.Thread(target=loop2, args=())

        t1.start()
        t2.start()

        t1.join()
        t2.join()

if __name__ == "__main__":
        main()



你可能感兴趣的:(Python多线程:thread、threading、queue)