Python进阶----线程基础,开启线程的方式(类和函数),线程VS进程,线程的方法,守护线程,详解互斥锁,递归锁,信号量

一丶线程的理论知识

什么是线程:

   1.线程是一堆指令,是操作系统调度的最小单位

   2.线程具有执行能力

​   3.线程依赖于进程

​   4.具有主从关系(人为定义,每一个进程都至少有一个主线程

二丶开启线程的两种方式(Thread)

类的方式开启线程

### 利用到Thread

from  threading import Thread

class MyThread(Thread):

    def run(self) -> None:		# 必须重写run函数
print(f'{self.name} 被开启了~~') if __name__ == '__main__':
t=MyThread() # 实例化一个自定义线程类对象
t.start() # 启动子线程
print('in 主线程')

函数的方式开启线程

### 函数开启线程
from threading import Thread def task(name):
print(f'在子线程中: {name}') if __name__ == '__main__': t=Thread(target=task,args=('abc',)) # 实例化线程对象
t.start() # 启动子线程 print('主~~~~')

三丶线程和进程之间的对比

进程VS线程:

   1.线程的启动速度 快于 进程的启动速度

   2.线程之间数据可以共享,进程之间不能数据共享(必须依靠队列才能实现)

   3.线程开销小,进程开销大

   4.在运行速度上,进程和线程是没有可比性.(两个不同的概念,线程具有执行能力,进程不具有执行能力)

   5.多进程/多线程: 同一时刻开启多个进程/线程, 并发(并行)执行

四丶线程的其他方法

两种:

   1.线程对象方法

   2.threading对象方法

# -*-coding:utf-8-*-
# Author:Ds from threading import Thread
import threading
import time ### 定义开启子线的方法
def task():
time.sleep(1) # 睡1秒, 保证所有的子线程都能存活1秒 以上
print(f'123')
print(threading.current_thread().name) #子线程对象名字 if __name__ == '__main__':
for i in range(6):
t=Thread(target=task,name='firstIn') #target指定子线程任务,name子线程名
t.start() ### 1. 线程对象方法
print(t.isAlive()) # 判断线程是否还存活
t.setName('32141') # 设置name属性
print(t.getName()) # 获得线程名 ### 2 threading模块方法
print(threading.current_thread()) #线程对象
print(threading.enumerate()) # 列表 [<_MainThread(MainThread, started 10748)>, <Thread(firstIn, started 3696)>,]
print(threading.active_count()) # 获取活跃的线程数量 (包括主线程 ) 7个
print('主线程')

五丶守护进程

什么是守护线程:

   1.守护线程必须等待所有的非守护线程以及主线程结束之后才结束

   2.本质还是子线程,在开启前被设置成守护线程.

### 守护线程

from threading import Thread
import time def task(name):
print(f'{name} is running')
time.sleep(1) # 当主线程结束了,当前守护线程也就结束了
print(f'{name} is over') if __name__ == '__main__':
t = Thread(target=task,args=('abc',))
t.daemon = True # 将一个子线程设置为守护线程
t.start() print('主线程')

容易产生歧义:

   1.首先 要明确, 在同一时刻, CPU只允许一个任务的存在, 遇到IO阻塞进行任务切换

   2.守护进程VS守护线程

      守护线程:必须等待所有的非守护线程执行完毕以及主线程执行完毕,才能结束

      守护进程:守护进程不会等待所有的非守护进程完毕才结束.只要主进程GG,守护进程GG

   3. 守护线程要是伴随着主线程结束而结束. 试想: 一个主进程的结束标志是什么? 一个py程序的结束 或者 一个主线程的结束 . 进程是对资源的管理,通俗来说就是开了个内存空间. 明白了否? 转会到线程. 主线程结束是要等待所有的非守护线程运行完毕结束才结束, 守护线程则是伴随主线程结束而结束. 在代码上来说. 主线程只回非守护线程的子线程资源. 而守护线程是无主状态,主进程结束代表主进程结束. 主进程结束代表这一块空间消失. 守护线程也就不会存活.

### 守护线程:   

from threading import Thread
import time def foo():
print(123)
time.sleep(1) # sleep 表示要切换, 执行bar子线程
print("end123") def bar():
print(456) # 执行 守护线程必须等待非守护线程执行完毕才能结束
time.sleep(3)
print("end456") if __name__ == '__main__': t1=Thread(target=foo)
t2=Thread(target=bar) t1.daemon = True
t1.start()
t2.start()
print("main-------")

守护线程/进程总结:

      无论是进程还是线程,都遵循:守护xxx会等待主xxx运行完毕后被销毁

      需要强调的是:运行完毕并非终止运行

# 主进程在其代码结束后就已经算运行完毕了(守护进程在此时就被回收),然后主进程会一直等非守护的子进程都运行完毕后回收子进程的资源(否则会产生僵尸进程),才会结束,
# 主线程在其他非守护线程运行完毕后才算运行完毕(守护线程在此时就被回收)。因为主线程的结束意味着进程的结束,进程整体的资源都将被回收,而进程必须保证非守护线程都运行完毕后才能结束。

六丶互斥锁

含义:

   1.互斥锁,同步锁,锁.都是同一种锁LOCK

   2.在并发时,保证数据的安全('串行')

###互斥锁 实现 '并发' 

# -*-coding:utf-8-*-
# Author:Ds from threading import Thread
from threading import Lock # 这是线程的 互斥锁 import time x=100 def task(lock):
lock.acquire() # 加锁 实现 '并发' ,保证数据的安全性
global x
temp = x
time.sleep(0.1)
temp -= 1
x = temp
print(x)
lock.release() if __name__ == '__main__':
lock=Lock() # 实例化锁对象 #### 如果想要实现并发. 1.把所有的实例对象都添加列表中,2 join循环列表, 每一个线程都必须等待上一个线程执行完,必须等待上一个线程执行完 t_li=[] # 存放线程对象, 实现并发
for i in range(100): # 创建100个子线程
t=Thread(target=task,args=(lock,))
t_li.append(t)
t.start()
for el in t_li:
el.join() # 循环列表, 每一个线程都必须等待上一个线程执行完,必须等待上一个线程执行完
print(f'最后x:{x}')

七丶死锁现象,递归锁

死锁含义(Lock):

   一个资源被多次调用,多次调用资源未能释放,会造成一种互相等待的现象.在没有外力作用下,只能停留在这,此时的系统处于锁死状态.

死锁现象(2种):

   1.当一个进程或者一个线程一直占调用或者占用同一把锁Lock时,而不释放资源会导致其他进程/线程无法获得锁,就会出现锁死现象.一直出去阻塞acquire()状态

      代码见

Python进阶----线程基础,开启线程的方式(类和函数),线程VS进程,线程的方法,守护线程,详解互斥锁,递归锁,信号量的更多相关文章

  1. Python进阶----计算机基础知识(操作系统多道技术),进程概念, 并发概念,并行概念,多进程实现

    Python进阶----计算机基础知识(操作系统多道技术),进程概念, 并发概念,并行概念,多进程实现 一丶进程基础知识 什么是程序: ​   程序就是一堆文件 什么是进程: ​   进程就是一个正在 ...

  2. 《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)

    1.简介 上一篇介绍了POM的基础理论知识和非POM方式写脚本,这篇介绍利用页面工厂类(page factory)去实现POM,通过查看PageFactory类,我们可以知道它是一个初始化一个页面实例 ...

  3. 《手把手教你》系列基础篇(九十六)-java+ selenium自动化测试-框架之设计篇-跨浏览器(详解教程)

    1.简介 从这一篇开始介绍和分享Java+Selenium+POM的简单自动化测试框架设计.第一个设计点,就是支持跨浏览器测试. 宏哥自己认为的支持跨浏览器测试就是:同一个测试用例,支持用不同浏览器去 ...

  4. java线程基础巩固---采用多线程方式模拟银行排队叫号以及Runnable接口存在的必要性

    采用多线程模拟银行排队叫号: 关于银行拿排队号去叫号的过程我想不必过多解释了,就是有几个业务窗口,并行的处理业务,每处里完一个人,则会叫下一个排队的号去处理业务,一个人是不会被多个窗口工作人员叫号的, ...

  5. Object类中wait带参方法和notifyAll方法和线程间通信

    notifyAll方法: 进入到Timed_Waiting(计时等待)状态有两种方式: 1.sleep(long m)方法,在毫秒值结束之后,线程睡醒,进入到Runnable或BLocked状态 2. ...

  6. Object类中wait代餐方法和notifyAll方法和线程间通信

    Object类中wait代餐方法和notifyAll方法 package com.yang.Test.ThreadStudy; import lombok.SneakyThrows; /** * 进入 ...

  7. 创建线程方法&守护线程

    创建线程方法1. class mythread extends Thread{ 重写run方法 } mythread m=new mythread () 启动:m.start() 创建线程方法2. c ...

  8. 《手把手教你》系列基础篇(七十七)-java+ selenium自动化测试-框架设计基础-TestNG依赖测试- 上篇(详解教程)

    1.简介 今天主要是讲解和分享:TestNG中一个类中有多个测试方法的时候,多个测试方法的执行顺序或者依赖关系的问题.如果不用dependsOnMethods,testNG会自动根据@Test方法名称 ...

  9. 《手把手教你》系列基础篇(八十四)-java+ selenium自动化测试-框架设计基础-TestNG日志-上篇(详解教程)

    1.简介 TestNG还为我们提供了测试的记录功能-日志.例如,在运行测试用例期间,用户希望在控制台中记录一些信息.信息可以是任何细节取决于目的.牢记我们正在使用Selenium进行测试,我们需要有助 ...

随机推荐

  1. AttributeError: 'builtin_function_or_method' object has no attribute 'reshape'

    AttributeError: 'builtin_function_or_method' object has no attribute 'reshape' 读取.mat文件时,copy没加括号

  2. ModuleNotFoundError: No module named 'pymysql'

    出现此提示表示系统中没有安装PyMySQL,可以通过pip PyMySQL进行安装. 安装之后,执行import pymysql仍然不可用! why? 检查后发现系统中存在python2与python ...

  3. git修改提交作者和邮箱

    作用一名程序员,我们会经常混迹与不同的代码仓库,时常不同仓库会有作者信息验证.比如公司内建的gitlab一般会要求统一使用公司内部的域账号签名:github要求使用github账号签名等.因此,很容易 ...

  4. NIO网络访问模式实践

    1.创建NioNest12类 一个线程监听5个端口的事件 public class NioTest12 { public static void main(String[] args) throws ...

  5. API调试工具--------Postman

    Postman一款非常流行的API调试工具.其实,开发人员用的更多.因为测试人员做接口测试会有更多选择,例如Jmeter.soapUI等.不过,对于开发过程中去调试接口,Postman确实足够的简单方 ...

  6. Java基础 awt Button 鼠标放在按钮上背景颜色改变,鼠标离开背景颜色恢复

        JDK :OpenJDK-11      OS :CentOS 7.6.1810      IDE :Eclipse 2019‑03 typesetting :Markdown   code ...

  7. ES6 - 解构(数组和对象)

    解构对象 /** * 解构:快捷,方便 * * 对象解构 */ { var expense = { type: "es6", amount: "45" }; / ...

  8. SVN 从主干合并到分支库

    主干库:平时开发用的库, 分支库:中途需要进行上生产环境的库 分支库的版本从主干库拉过去就行 红色的为分支库. 创建的速度很快. 1.创建好后,在主干库添加一个文件. 2.然后分支库进行合并,这里用e ...

  9. sql server 利用存储过程http请求调用URL链接访问方法

    sp_configure ; GO RECONFIGURE; GO sp_configure ; GO RECONFIGURE; GO EXEC sp_configure 'Ole Automatio ...

  10. Win64 驱动内核编程-33.枚举与删除对象回调

    转载:http://www.voidcn.com/article/p-wulgeluy-bao.html 枚举与删除对象回调 对象回调存储在对应对象结构体里,简单来说,就是存储在 ObjectType ...