进程&&线程

进程和线程

进程

定义:进程就是一个程序在一个数据集上的一次动态执行过程

   进程一般由

程序、数据集、进程控制块

三部分组成。

数据集:

则是程序在执行过程中所需要使用的资源;
   

进程控制块:

用来记录进程的外部特征,描述进程的执行变化过程,系统可以利用它来控制和管理进程,它是系统感知进程存在的唯一标志。
 
 

线程

线程的出现是为了降低上下文切换的消耗,提高系统的并发性,并突破一个进程只能干一样事的缺陷,使到进程内并发成为可能。
 
 
区别和关系:
1.一个程序至少有一个进程,一个进程至少有一个线程.(进程可以理解成线程的容器)

线程:

是最小的执行单元,不能独立执行,共享所属进程的资源
      一个线程可以创建和撤销另一个线程,同一进程中线程可并发
进程:是最小的资源分配单元,不能资源共享,有独立的资源空间

python的GIL

GIL:python中,在同一时刻只能有一个线程进入解释器

threading的两种调度方法

直接调用:

  1 import threading
  2 import time
  3 def Hed(num):
  4     print(num)
  5     time.sleep(3)
  6 if __name__ =="__main__":
  7     t1 = threading.Thread(target=Hed,args=(10,))
  8     t1.start()
  9     t2 = threading.Thread(target=Hed,args=(20,))
 10     t2.start()
 11     print("ending")

继承调用:

  1 class MyThread(threading.Thread):
  2     def __init__(self, num):
  3 
  4 
  5         threading.Thread.__init__(self)
  6         self.num = num
  7 
  8     def run(self):  # 定义每个线程要运行的函数
  9         print("running on number:%s" % self.num)
 10         time.sleep(3)
 11 if __name__=='__main__':
 12     t1 = MyThread(1)
 13     t2 = MyThread(2)
 14     t1.start()
 15     t2.start()

join和setDaemon

join():在子线程完成运行之前,这个子线程的父线程将一直被阻塞。

setDaemon(True):

         将线程声明为守护线程,必须在start() 方法调用之前设置, 如果不设置为守护线程程序会被无限挂起。这个方法基本和join是相反的。

         正常情况下:当我们在程序运行中,执行一个主线程,如果主线程又创建一个子线程,主线程和子线程 就分兵两路,分别运行,那么当主线程完成

         想退出时,会检验子线程是否完成如果子线程未完成,则主线程会等待子线程完成后再退出。但是有时候我们需要的是只要主线程

         完成了,不管子线程是否完成,都要和主线程一起退出,这时就可以 用setDaemon方法

一般情况下:

  1 import threading
  2 import time
  3 def Music():
  4 
  5     print("Listen music...........%s"%time.ctime())
  6     time.sleep(3)
  7     print("Stop music..............%s"%time.ctime())
  8 
  9 def Videos():
 10 
 11     print("See videos ............%s"%time.ctime())
 12     time.sleep(5)
 13     print("Stop videos............%s"%time.ctime())
 14 
 15 
 16 t1 = threading.Thread(target=Music)
 17 t2 = threading.Thread(target=Videos)
 18 
 19 if __name__ == '__main__':
 20 
 21     t1.start()
 22     t2.start()
 23     print('end ..................%s'%time.ctime())

结果:

NTG}PT8JHNWI(T{2L`@T3]Q

 

 

如果: t1 = threading.Thread(target=Music())

          t2 = threading.Thread(target=Videos())

结果:会和一般的进程执行相同没有并发

7OO]PIU`EL6FWNDKLO_$AJN

 

 

加t1.join()后结果:

O91(7NTG@5E3XR3C%09DF)I

加t2.join()后结果:

IE1S)MNHT~X(1~5]@KSBQGF

 

加t1.setDaemon(True)后结果:

[U`E[ACGIA17J%K@(SCCL(B

原因:主进程在等待videos这个进程执行完了才是真的结束了,输出end….并不是真的主进程结束,

         t1是守护进程那么t2才是主进程结束的标志

 

加t2.setDaemon(True)后结果:

image

原因:t2是守护进程了,所以主进程结束的标志看t1,t1一结束标志主进程结束了,那么后面的守护进程就不再执行了

其他方法:

# run():  线程被cpu调度后自动执行线程对象的run方法
# start():启动线程活动。
# isAlive(): 返回线程是否活动的。
# getName(): 返回线程名。
# setName(): 设置线程名。

threading模块提供的一些方法:
# threading.currentThread(): 返回当前的线程变量。
# threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
# threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。

猜你喜欢

转载自www.cnblogs.com/janus1345/p/9200546.html