这篇文章主要介绍关于Python中线程、进程、协程的简介,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

一、线程(Thread)

  1、定义:线程是操作系统能进行运算调度的最小单位,它包含在进程中,是进程的实际运作单位,一条线程是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。简单理解:线程是一系列指令的集合,操作系统通过这些指令调用硬件。

  2、同一个线程中的所有线程共享同一个内存空间资源,

二、进程(Progress)

  1、定义:一个程序对各资源管理和调用的集合就是进程,比如QQ对网卡、内存、硬盘的调度和管理。对于操作系统来说,某一个进程是统一的整体。进程操作CPU就要先创建一个线程。进程本身是一个资源集合,执行需要靠线程。

三、线程和进程的区别

  1、同个进程的线程之间共享内存空间,包括数据交换和通信,但不同进程之间的内存是独立的

  2、子进程是克隆了一份父进程的数据,子进程之间是互相独立的,不能互相访问,数据也不能共享。

  3、两个进程要通信,必须通过一个中间进程代理来实现。

  4、一个线程可以操作同一个进程中的其他线程,但是进程只能操作子进程

  5、对主线程的修改,可能会影响到其他的子线程,因为他们共享内存数据,但对主进程的修改,不会影响其他子进程。

四、多线程的代码:

importthreadingimporttimeclassMyThread(threading.Thread):"""#用自定义一个子类的方式来启动线程"""def__init__(self,n):super(MyThread,self).__init__()self.n=ndefrun(self):print("你好,%s"%self.n)time.sleep(2)start_time=time.time()thread_list=[]#启动50个线程foriinrange(50):t1=MyThread("t%s"%i)t1.start()thread_list.append(t1)#等待所有线程执行完毕后主线程再继续执行foriinthread_list:i.join()print("总共执行时间:%s"%float(time.time()-start_time))

五、全局解释器锁(GIL)

  1、定义:GIL 是最流行的 CPython 解释器(平常称为 Python)中的一个技术术语,中文译为全局解释器锁,其本质上类似操作系统的 Mutex(即互斥锁,意思是我修改的时候你不能修改,也就是锁的意思)

  2、功能:在 CPython 解释器中执行的每一个 Python 线程,都会先锁住自己,以阻止别的线程执行,这样在同个时间一个CPU只执行一个线程。当然,CPython 不可能容忍一个线程一直独占解释器,check interval 机制会在一个时间段后释放前面一个线程的全局锁执行下一个线程,以达到轮流执行线程的目的。这样一来,用户看到的就是“伪”并行,即 Python 线程在交替执行,来模拟真正并行的线程。

  3、CPython 引进 GIL,可以最大程度上规避类似内存管理这样复杂的竞争风险问题,有了 GIL,并不意味着无需去考虑线程安全,因为即便 GIL 仅允许一个 Python 线程执行,但别忘了 Python 还有 check interval 这样的抢占机制。所以就要引入线程锁的机制,保证同个时间只有一个线程修改数据。

  4、线程锁的代码如下

importthreadingimporttimenum=0lock_obj=threading.Lock()defrun():#申请锁,使别的线程进不来lock_obj.acquire()globalnumtime.sleep(1.1)num=num+1#解锁,解锁后别的线程可以进来lock_obj.release()t_list=[]start_time=time.time()#启动1000个线程foriinrange(100):t1=threading.Thread(target=run)t1.start()t_list.append(t1)foriint_list:i.join()time.sleep(3)print("num:%d"%num)print("time:%f"%float(time.time()-start_time))

六、递归锁:

  1、定义:一个锁套另外一个锁,形成锁止循环,这种情况就要用到递归锁RLOCK

importthreading,timedefrun1():print("grabthefirstpartdata")lock.acquire()globalnumnum+=1lock.release()returnnumdefrun2():print("grabthesecondpartdata")lock.acquire()globalnum2num2+=1lock.release()returnnum2defrun3():lock.acquire()res=run1()print('--------betweenrun1andrun2-----')res2=run2()lock.release()print(res,res2)num,num2=0,0#这里如果用Lock()就会无限循环,找不到具体用哪个钥匙打开锁,如果用RLock就不会,如果又多重锁嵌套的情况一定要用递归锁lock=threading.Lock()foriinrange(1):t=threading.Thread(target=run3)t.start()whilethreading.active_count()!=1:print("当前活跃的线程数:",threading.active_count())else:print('----allthreadsdone---')print("打印num和num2:",num,num2)

七、信号量(Semaphore)  

  1、允许同时间最多几个线程进入执行,每出来一个进去一个,同时保持预先设置的线程最大允许数量。

importthreading,timedefrun(n):semaphore.acquire()time.sleep(1)print("runthethread:%s\n"%n)semaphore.release()if__name__=='__main__':semaphore=threading.BoundedSemaphore(5)#最多允许5个线程同时运行foriinrange(22):t=threading.Thread(target=run,args=(i,))t.start()whilethreading.active_count()!=1:pass#printthreading.active_count()else:print('----allthreadsdone---')#print(num)

八、事件(Event):

  1、定义:通过标识位和状态,来实现线程之间的交互。简单说,就是一个标志位,只有两种状态,一种是设置(Event.set()),一直是没有设置(Event.clear())。

  2、以下代码实现一个简单事件,一个线程控制红绿灯,另外一个线程控制车子,当红绿灯是红色的时候,车子停止,绿的时候,车子行驶的效果

importtimeimportthreadingevent=threading.Event()deflighter():count=0event.set()#刚开始的标识位先设置绿灯whileTrue:if5<count<10:#改成红灯event.clear()#把标志位清了print("\033[41;1mredlightison....\033[0m")elifcount>10:event.set()#变绿灯count=0else:print("\033[42;1mgreenlightison....\033[0m")time.sleep(1)count+=1defcar(name):whileTrue:ifevent.is_set():#代表绿灯print("[%s]running..."%name)time.sleep(1)else:print("[%s]seesredlight,waiting...."%name)event.wait()print("\033[34;1m[%s]greenlightison,startgoing...\033[0m"%name)light=threading.Thread(target=lighter,)light.start()car1=threading.Thread(target=car,args=("Tesla",))car1.start()

 3、Event类还有两个方法,wait()等待被设定,isset()判断是否被设定

以上是关于Python中线程、进程、协程的简介的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注亿速云行业资讯频道!