python 多线程

来源:互联网 发布:md5加盐加密java代码 编辑:程序博客网 时间:2024/06/05 16:34
多线程
多线程     基本概念        即1个进程中可以开启多条线程,每条线程可以并行(同时)执行不同的任务。     线程的并行        并行即同时执行。比如同时开启3条线程分别下载3个文件(分别是文件A、文件B、文件C。     多线程并发执行的原理        在同一时间里,CPU只能处理1条线程,只有1条线程在工作(执行)。多线程并发(同时)执行,其实是CPU快速地在多条线程之间调度(切换),如果CPU调度线程的时间足够快,就造成了多线程并发执行的假象     多线程优缺点        优点            (1)能适当提高程序的执行效率。            (2)能适当提高资源利用率(CPU、内存利用率)        缺点            (1)开启线程需要占用一定的内存空间(默认情况下,主线程占用1M,子线程占用512KB),如果开启大量的线程,会占用大量的内存空间,降低程序的性能。            (2)线程越多,CPU在调度线程上的开销就越大。            (3)程序设计更加复杂:比如线程之间的通信、多线程的数据共享
以下是一些示例:
class Mythread(threading.Thread):    def __init__(self):        threading.Thread.__init__(self)        print("Mythread")    def run(self):        for i in range(1,11):            print(i)            time.sleep(1)    def start(self):        print("开始Mythread")        threading.Thread.start(self)t=Mythread()t.start()t.join()            #阻断当前线程,当加入的线程执行完成后,当前线程才能继续print("main......")
下面解释一下示例代码中用到的方法:
'''start:开始执行线程,注意如果重写了start一定要调用父类的startrun:会在start之后自动调用join:线程阻塞方法,谁调用谁阻塞,哪个线程调用,哪个线程阻塞,直到join中指定的时间或是加入的线程执行完成之后'''
运行结果先输出1-10,最后在输出main....所以说join的作用也体现出来了,谁调用谁阻塞,main..作为主线程调用了join
所以等到线程t运行完了以后,才会执行
import threading
import time
class Thread1(threading.Thread):
    def run(self):
        for i in range(1,11):
            if i == 3:
                condition.acquire()
                condition.wait()
                condition.release()
            print(i)
            time.sleep(1)class Thread2(threading.Thread):
    def run(self):
        for i in range(30,19,-1):
            if i == 25:
                condition.acquire()
                condition.notify()
condition.release()            print(i)            time.sleep(1)lock=threading.Lock()condition=threading.Condition(lock=lock)Thread1().start()Thread2().start()
wait:让线程陷入休眠状态
notify:让当前休眠的线程继续工作
但是在使用这一类的方法之前需要有condition中的两个方法的支持
分别是condition.acquire()和condition.release()
这两个方法其实是线程锁下面简短的解释:

对于多线程来说,最大的特点就是线程之间可以共享数据,那么共享数据就会出现多线程同时更改一个变量,使用同样的资源,而出现死锁、数据错乱等情况。假设有两个全局资源,a和b,有两个线程thread1,thread2. thread1占用a,想访问b,但此时thread2占用b,想访问a,两个线程都不释放此时拥有的资源,那么就会造成死锁。对于该问题,出现了Lock。 当访问某个资源之前,用Lock.acquire()锁住资源,访问之后,用Lock.release()释放资源。

以下是一个在线程中很经典的一个和尚吃馒头的例子
需求:四个和尚,一个做馒头的三个吃馒头的,做馒头的需要先做10个馒头然后叫醒三个吃馒头的,之后自己进入休眠
三个和尚一个一个去拿馒头,只要有一个和尚发现没馒头了,就去叫醒做馒头的,之后三个吃馒头的去进行休眠
就这样一直循环。class zhengThread(threading.Thread):    def __init__(self,name=None):        threading.Thread.__init__(self);        self.name=name    def run(self):        while True:            condition.acquire()            if len(guo) == 0:                for i in range(1,11):                    guo.append(i)                    print("做出第{0}个馒头".format(i))                    time.sleep(1)                condition.notify_all()            condition.release()            condition2.acquire()            condition2.wait()            condition2.release()class chiThread(threading.Thread):    def __init__(self,name=None):        threading.Thread.__init__(self);        self.name=name    def run(self):        while True:            mantou=None            condition.acquire()            if len(guo) == 0:                condition2.acquire()                condition2.notify()                condition2.release()                condition.wait()            else:                mantou=guo.pop()            condition.release()            if mantou is not None:                print("{0}正在开始吃第{1}个馒头".format(self.name,mantou))                time.sleep(random.choice([1,2,3,4,5]))import randomguo=[]lock=threading.Lock()condition=threading.Condition(lock=lock)    #吃的锁lock2=threading.Lock()condition2=threading.Condition(lock=lock2)  #蒸的锁zhengThread(name="大头和尚").start()chiThread(name="白眉和尚").start()chiThread(name="花和尚").start()chiThread(name="牛鼻子和尚").start()
如果看明白了这个例子也就可以说对线程掌握的差不多了,希望可以帮助到初学线程的朋友!