python线程、进程

来源:互联网 发布:网店优化方案 编辑:程序博客网 时间:2024/06/04 19:47

进程和线程

进程:进程是程序的一次执行,每个进程都有自己的地址空间、内存、数据栈,以及其他记录其运行轨迹的辅助数据。操作系统管理在其上面运行的所有进程,并为这些进程公平的分配时间。

线程:(轻量型进程)所有的线程都运行在同一个进程中,共享相同的运行环境。

单线程和多线程

单线程:

单线程中处理器要处理多个任务时,必须对这些任务安排优先级,先执行谁后执行谁。

onethread.py

from time import *def movie(name,loop):            #线程1    for i in range(loop):        print("我在电影:%s,现在是:%s"%(name,ctime()))        sleep(2)def music(name,loop):            #线程2    for i in range(loop):        print("我在听音乐:%s,现在是:%s"%(name,ctime()))        sleep(2)if __name__ == "__main__":    movie("爱我别跑",2)    music("流星雨",3)

多线程:

Python通过thread库和threading库提供对线程的支持。thread库和threading库的区别:

  • thread库提供了低级别的、原始的线程以及一个简单的锁;
  • threading库是基于Java的线程模式设计,锁lock和条件变量condition在Java中是对象的基本行为(每一个对象都自带了锁和条件变量),而在Python中则是独立的对象;
  • thread库不支持守护线程,也就是当主线程退出时,所有的子线程都会强行退出,不管其工不工作;
  • threading库支持守护线程,主线程退出后仍在工作的子线程不会退出。
所以请使用threading库。

threads1.py

from time import *import threading#线程1def music(name,loop):    for i in range(loop):        print("我在听:%s,现在是%s"%(name,ctime()))        sleep(2)#线程2def movie(name,loop):    for i in range(loop):        print("我在看:%s,现在是%s"%(name,ctime()))        sleep(2)#创建空数组用来装载线程1,2threads =[]#创建线程t1,并添加到线程组threadst1 = threading.Thread(target=music,args=("后来",2))threads.append(t1)#创建线程t2,并添加到线程组threadst2 = threading.Thread(target=movie,args=("超人3",2))threads.append(t2)if __name__ == "__main__":    #启动线程    for i in threads:        i.start()  #开始线程活动    #守护线程    for i in threads:        i.join()   #等待线程终止    print("运行结束了。")


可以看到两个线程并行工作!!!!!

threading.Thread(target=,args=(),name=None,group=None,kwargs={})

  • target表示调用的对象;
  • args表示调用对象的位置参数元组;
  • kwargs表示调用对象的字典;
  • name表示该线程名;
  • group实际上不使用。

上面的例子中可发现线程的创建有些麻烦,每创建一个线程需要创建一个t(t1,t2,t3...)当创建的线程很多的时候这样极其不方便,

下面是优化的多线程:

threads2.py

from time import sleep,ctimeimport threadingdef super_player(file_,time):    for i in range(2):        print('开始播放:%s!%s'%(file_,ctime()))        sleep(time)#播放文件和播放时长dicts ={'真爱.mp3':2,'阿凡达.mp4':5,'我和你':4}#创建线程空数组,用于存放线程threads =[]files = range(len(dicts))#创建线程(遍历字典)并添加到线程数组内for file_,time in dicts.items():    t = threading.Thread (target=super_player,args=(file_,time))    threads.append(t) #if __name__ =='__main__':    #启动线程    for i in files:        threads[i].start()    #守护线程    for i in files:        threads[i].join()    print('end all:%s'%ctime())

自定义线程类

除了使用python提供的线程外,我们可以根据自己的需求定义自己的线程类:

mythreads.py

import threadingfrom time import sleep,ctime#创建线程类class MyThread(threading.Thread):    def __init__(self,func,args,name=''):        threading.Thread.__init__(self)   #super().__init__()        self.func = func        self.args = args        self.name = name    def run(self):        self.func(*self.args)  #python2不支持这种方式def super_play(file_,time):    for i in range(2):        print("开始播放:%s!%s"%(file_,ctime()))        sleep(time)dicts ={"真爱.mp3":3,"阿凡达.mp4":5,"我和你.mp3":5}threads =[]files = range(len(dicts))for file_,time in dicts.items():    t = MyThread(super_play,(file_,time),super_play.__name__)    threads.append(t)if __name__=='__main__':    #启动线程    for i in files:        threads[i].start()    for i in files:        threads[i].join()    print('all end:%s'%ctime())

多进程技术

多进程使用multiprocessing模块,与多线程的threading模块用法类似。

多进程的优势

multiprocessing提供了本地和远程的并发性,有效地通过全局解释锁(GIL)来使用进程而不是线程。由于GIL的存在,在CPU密集型的程序当中,使用多线程并不能有效地利用多核CPU的优势,因为一个解析器在同一时刻只会有一个线程在执行。所以muitiprocessing模块可以充分利用硬件的多处理器来进行工作。

多进程使用的multiprocessing模块使用Process对象来创建一个进程,Process对象使用和多线程的Thread对象使用方法相同,

  • start() 开启进程活动;
  • run()   运行进程
  • join() 等待进程的终止
multiprocessing.Process(target=,args=(),name=,kwargs={},group=None)
  • target表示调用的对象;
  • args表示调用对象的位置参数,元组;
  • kwargs表示调用对象的字典,字典{};
  • name进程的名字;
  • group实际上不使用。

process.py

from time import *import multiprocessingdef surper_player(file_,time):    for i in range(2):        print('start playing:%s.%s'%(file_,ctime()))        sleep(time)lists ={'loving.mp3':3,'makeloving.mp4':5}threads =[]files =range(len(lists))#创建进程for file_,time in lists.items():    t =multiprocessing.Process(target=surper_player,args=(file_,time))    threads.append(t)if __name__ =="__main__":    #启动进程    for t in files:        threads[t].start()    for t in files:        threads[t].join()

运行结果和多线程几乎一样。。。

Pipe和Queue

IPC进程间通信

pipe.py

import multiprocessingfrom time import ctimedef proc1(pipe):    pipe.send('hello')                       #进程从pipe一端输入对象    print('proc1 rec:',pipe.recv(),ctime()) #被pipe另一端的进程接收def proc2(pipe):    print('proc2 rec:',pipe.recv(),ctime()) #被pipe一段的进程接收    pipe.send('hello,too.')                  #进程从pipe另一端输入对象#这里的pipe双向的,pipe对象建立的时候,返回一个含有两个元素的表,每个元素代表pipe的一端,对pipe的某一端调用send()方法来传送对象,在另一端使用recv()接收if __name__ =="__main__":    multiprocessing.freeze_support()    pipe = multiprocessing.Pipe()    p1 = multiprocessing.Process(target=proc1,args=(pipe[0],))    p2 = multiprocessing.Process(target=proc2,args=(pipe[1],))    p1.start()    p2.start()    p1.join()    p2.join()
queque.py

import multiprocessing,osfrom time import *def inputQ(queue):    info = str(os.getpid()) + 'put():' + str(ctime())    queue.put(info)def outputQ(queue,lock):    info = queue.get()    lock.acquire()    print((str(os.getpid()) + 'get():' + info))    lock.release()if __name__ =="__main__":    record1 = []    record2 = []    lock = multiprocessing.Lock()    queue = multiprocessing.Queue(3)    for i in range(10):        process = multiprocessing.Process(target=inputQ,args=(queue,))        process.start()        record1.append(process)            for i in range(10):        process =multiprocessing.Process(target=outputQ,args=(queue,lock))        process.start()        record2.append(process)    for i in record1 :        i.join()    queue.close()    for i in record2:        i.join()







0 0