• 线程了解以及创建线程的Threading模块中的部分方法


    了解线程

    1.什么是线程

    在传统的操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程
    线程,其实就是一条流水线的过程,一条流水线必须属于一个车间,一个车间的工作过程是一个进程
    车间负责把资源整合到一起,是一个资源单位,而一个车间内至少有一个流水线
    流水线的工作需要带能源,电源就相当于CPU
    总而言之,进程只是用来把资源集中到一起(进程就是一个资源单位,或者说是资源集合),而线程才是cpu上的执行单位
    
    多线程:就是在一个进程中存在多个控制线程,多个控制线程共享该进程的地址空间,相当于一个车间有多条流水线,都共用一个车间的资源
    

    2.线程的创建开销小

    创建进程的开销要远大于线程?
    这个答案显然是否定的,就上述例子来说,你创建一个车间的时间就相当于创建一个进程的时间,而创建一个流水线的时间就好比创建一个线程。
    要是创建一个车间(也就是进程),你需要去重新划分一块地(也就是重新分配内存空间),而创建一条流水线(也就是创建一个线程),是直
    接再原来的车间里面直接创建(也就是在原来的进程中分配一块资源)
    所以我们可以理解创建线程的时间要远远小于创建一个进程的时间
    

    3.线程进程的区别

    1.线程共享创建它的地址空间;进程有自己的地址空间
    2.线程可以直接访问其进程的数据段;进程有自己的父进程的数据段副本
    3.线程可以直接与进程的其他线程通信;进程必须使用进程间通讯与同级进程通信
    4.新线程很容易创建;新进程需要复制父进程
    5.线程可以对统一进程的线程进行很大的控制;进程只能对子进程进行控制
    6.对主线程的更改(取消、优先级更改等)可能会影响进程的其他线程的行为;对父进程的更改不会影响子进程
    

    4.为什么要使用多线程

    多线程是指,在一个进程中开启多个线程,简单来讲;如果多个任务共用一块地址空间,那么必须在一个进程内开启多个线程,详细分为四点:
    	1.多线程共享一个进程的地址空间
    	2.线程比进程更轻量级,线程比进程更容易创建可撤销,在许多操作系统中,创建一个线程比创建一个进程快很多倍,再有大量线程需要
    	动态修改时,这一特征很有用
    	3.若多个线程都是cpu密集型的,那么并不能获得性能上的增强,但是如果存在大量的计算和大量的io处理,拥有多个线程允许这些活动
    	彼此重叠运行,从而加快程序执行的速度
    	4.再cpu系统中,为了最大限度利用多核,可以开启多个线程,比开进程开销要小的多(这一条并不适用于python)
    

    5.多线程应用举例

    开启一个字处理软件进程,该进程肯定需要办不止一件事情,比如监听键盘输入,处理文字,定时自动将文字保存到硬盘,这三个任务操作
    的都是同一快数据,因而不能用多进程。只能在一个进程里并发的开启三个线程,如果时单线程,那就只能是,做一项任务时不能使用其他
    功能
    

    6.经典线程模型(了解)

    - 多个线程共享一个进程的地址空间的资源,是对一台计算机上多个进程的模拟,又是也称线程为轻量级的进程
    - 而对一台计算机上多个进程,则共享物理内存、磁盘、打印机等其他物理资源
    - 多线程的运行也和多进程类似,是cpu在多个进程间的快速切换
    - 不同点在于进程之间是相互竞争的,会出现争抢资源的情况。而同一个进程是由一个程序员的程序创建的,所以同一进程内的线程是合作关系,
    一个线程可以访问另一个线程的内存地址,大家都是共享的
    - 类似于进程,每个线程也有自己的堆线
    - 不同于进程线程库无法利用时钟强制线程让出cpu,可以调用threading_yield运行线程自动放弃cpu,让另外一个线程运行
    

    threading模块介绍

    multiprocessing模块完全模仿了threading模块的接口,二者在使用层面,有很大的相似性。
    

    1.开启线程的两种方式

    方式一:
    
    	from threading import Thread
    	
    	def foo():
    		print("这是一个新开子线程")
    	
    	t = Thread(target=foo)
    	t.start()
    	print("这个在执行的是主线程")
    
    方式二:
    	
    	from threading import Thread
    	
    	class My_foo(Thread):
    		def run(self):
    			print("这是一个新开子线程")
    	
    	t = My_foo()
    	t.start()
    	print("这个在执行的是主线程")
    

    2.在一个进程下开启多个线程与在一个进程下开启多个子进程的区别

    1.开启线程的速度快
    2.线程使用的是同一个pid,进程都是由不同的pid号
    3.线程间数据共享,进程没有数据的共享,只能依靠进程间通讯
    

    3.线程相关的其他用法

    Thread实例对象的方法
    - isAlive() 返回线程是否存活,(这个好像和 对象.is_alive() 方法没啥区别)
    	
    	import time
    	from threading import Thread
    
    	def foo():
    		time.sleep(4)
    		print("1")
    
    	t = Thread(target=foo)
    
    	t.start()
    	time.sleep(6)
    	print(t.is_alive())
    	print(t.isAlive())
    
    - getName():返回线程名 (这个好像也和 对象.name 方法没啥区别)
    - setName():设置线程名 (这个好像也和 对象.name = "想设置的值" 方法没啥区别)
    	这两段代码就不写了,太low了,两个方法,就相当于换了个外套就出来溜达了
    	
    threading模块提供的一些方法:
    - threading.currentThread():返回当前的线程变量
    	- 打印的类似这种:<_MainThread(MainThread, started 8084)>  (这个是主线程)
    					  <Thread(Thread-1, started 11412)>   (这个是子线程)
    - threading.enumerate():返回一个包含正在运行的线程list。正在运行指进程启动后、结束前,不包括启动前和终止后的线程。
    - threading.activeCount():返回正在运行的线程数量  (其实就是把enumerate()中的正在运行的线程数量统计了一下)
    

    4.守护线程

    - 和守护进程的定义方法是一样的,无论是进程还是线程,都遵循:守护线程/进程会等待主线程/进程运行完毕后被销毁
    - 需要强调的是运行完毕并非终止运行
    	- 对于主进程来说:运行完毕是指主进程代码运行完毕
    	- 对于主线程来说:运行完毕指的是主线程所在的进程内所有非守护线程统统运行完毕,主线程才算运行完毕
    详解:
    	- 主进程 在其代码结束后就已经运行完毕了(守护进程在此时就会被回收),然后主进程会一直等非守护进程的子进程都运行完毕后
    	回收子进程的资源,如果不这样设计就会产生僵尸进程,才会结束
    	- 主线程 在其他非守护线程运行完毕后才算运行完毕(守护线程在此时就会被回收)。因为主线程的结束意味着进程的结束,进程整体
    	的资源都会被回收,而进程必须保证非守护线程都运行完毕后才能结束
  • 相关阅读:
    asp.net应用程序的生命周期和iis
    跨网页公布技术
    Java面试题:异常、静态变量
    js省市级联
    python基础之介绍
    Java学习(二)有关Tomcat的进一步理解与运用
    Java学习(一)环境的配置和软件的使用
    构造方法
    自言自语
    小小叹
  • 原文地址:https://www.cnblogs.com/xiongchao0823/p/11536138.html
Copyright © 2020-2023  润新知