python 线程 ~~ ~~~为面试开辟VIP通道~~~~~测试、死锁、全局变量共享、守护主线程等。。。。。。(1)

简介: 线程(英语:thread)是操作系统能够进行运算调度的最小单位。线程很重要,通过本篇文章可以让你们很好的了解线程的传参、线程执行规则、守护主线程、线程间共享全局变量、进程互斥锁、死锁进程怎么解决。希望对你们有所帮助。

在了解线程之间的操作及进程死锁之前先来了解一下什么是进程?以下是官方的解释。

线程(英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。在Unix System V及SunOS中也被称为轻量进程(lightweight processes),但轻量进程更多指内核线程(kernel thread),而把用户线程(user thread)称为线程。

线程是独立调度和分派的基本单位。线程可以为操作系统内核调度的内核线程,如Win32线程;由用户进程自行调度的用户线程,如Linux平台的POSIX Thread;或者由内核与用户进程,如Windows 7的线程,进行混合调度。

同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。但同一进程中的多个线程有各自的调用栈(call stack),自己的寄存器环境(register context),自己的线程本地存储(thread-local storage)。

一个进程可以有很多线程,每条线程并行执行不同的任务。

在多核或多CPU,或支持Hyper-threading的CPU上使用多线程程序设计的好处是显而易见,即提高了程序的执行吞吐率。在单CPU单核的计算机上,使用多线程技术,也可以把进程中负责I/O处理、人机交互而常被阻塞的部分与密集计算的部分分开来执行,编写专门的workhorse线程执行密集计算,从而提高了程序的执行效率。


看着是不是非常的晕,没关系,下面让我们用实例来享受线程带来的舒适。

1、线程之元组传参

# TODO                鸟欲高飞,必先展翅
# TODO                 向前的人 :Jhon
#  TODO 元组
import threading
import time
def task(count):
    for i in range(count):
        print("正在工作")
        time.sleep(0.2)
    else:
        print("工作结束")
if __name__ == '__main__':
    #创建子线条程
    task_thred=threading.Thread(target=task,args=(5,))
    task_thred.start()

结果

#   TODO  字典
import threading
import time
def task(count):
    for i in range(count):
        print("正在工作")
        time.sleep(0.2)
    else:
        print("工作结束")
if __name__ == '__main__':
    #创建子进程
    task_thred=threading.Thread(target=task,kwargs={"count":6})
    task_thred.start()

因为

微信图片_20221010125003.png

结果

微信图片_20221010125052.png

2、线程之字典传参

task_thred=threading.Thread(target=task,kwarg={"count":6})创建子线程并将字典{“count”:6}传给task(count)函数,函数中count形参接收。其中target=task,target就是目标,也就是目标函数的意思。字典就类似于json字符串,找个网页单机右键检查找到网络下面的全部,找一个js文件打开(可以不一定是js文件,其他的也可以)刷新一下你就可以发现标头里的都是以字符串显示的微信图片_20221010125132.png

image.png

task_thred.start()就是将上面创建的线程开启,注意一定要开启线程,不然线程开启不了程序无法执行。time.sleep(0.2),休眠0.2秒,看起来卡顿卡顿的,更好的看出进程执行的过程

3、线程执行规则

很显然是无序的,线程和进程都是用于资源调度,是随机分配的,所以是都是无序的。下面通过例子来看一下。image.png

#  TODO  线程之间执行时无序的
import threading
import time
def work1():
    time.sleep(1)
    print("当前的线程是:",threading.current_thread().name)
if __name__ == '__main__':
    for _ in range(5):
        work_thred=threading.Thread(target=work1)
        work_thred.start()

结果:

第一次执行结果image.png

第二次执行结果:

image.png

我们对比两次的执行结果可以发现第一次执行的线程顺序是: 4->5->1->3->2,而蒂维茨执行的县城顺序是: 3->5->2->1->4,很显然两次的执行顺序不一致,所以线程的执行是没有顺序的

4、测试主次线程权限,如何消除权限???又如何巩固主线程的掌控权

测试主线程是否会等待子线程执行完毕关闭,通过下面的例子你可以很好的了解。

# TODO 测试主线程是否会等待子线程执行完毕关闭
import time
import threading
def show_info():
    for i in range(5):
        print("test,",i)
        time.sleep(1)
if __name__ == '__main__':
    show_thted=threading.Thread(target=show_info)
    show_thted.start()
    time.sleep(1.5)
    print("结束")

结果:

image.png

我们可以发现主线程结束后,子进程也停止了执行,达到预期目的,方法可行。

4.1、方法一:

创建进程的时候加入守护进程daemon

# TODO 测试主线程是否会等待子线程执行完毕关闭
import time
import threading
def show_info():
    for i in range(5):
        print("test,",i)
        time.sleep(1)
if __name__ == '__main__':
    show_thted=threading.Thread(target=show_info,daemon=True)
    show_thted.start()
    time.sleep(1.5)
    print("结束")

结果:

image.png

我们可以发现主线程结束后,子进程也停止了执行,达到预期目的,方法可行

4.2、方法二

难道必须在创建进程的时候就要放入守护进程吗?

# TODO 测试主线程是否会等待子线程执行完毕关闭
import time
import threading
def show_info():
    for i in range(5):
        print("test,",i)
        time.sleep(1)
if __name__ == '__main__':
    show_thted=threading.Thread(target=show_info)
    show_thted.setDaemon(True)
    show_thted.start()
    time.sleep(1.5)
    print("结束")

结果:

image.png这样是不是也可以确保主线程停止后子线程跟着停止,ok,达到效果,方法可行。但是你们有没有发现这样很多余,明明一行代码就可以实现的,为什么要多行代码执行呢,但是作为一个方法,记住还是很有必要的。


目录
相关文章
|
21天前
|
Java
【多线程面试题二十五】、说说你对AQS的理解
这篇文章阐述了对Java中的AbstractQueuedSynchronizer(AQS)的理解,AQS是一个用于构建锁和其他同步组件的框架,它通过维护同步状态和FIFO等待队列,以及线程的阻塞与唤醒机制,来实现同步器的高效管理,并且可以通过实现特定的方法来自定义同步组件的行为。
【多线程面试题二十五】、说说你对AQS的理解
|
22天前
|
Java
【多线程面试题十六】、谈谈ReentrantLock的实现原理
这篇文章解释了`ReentrantLock`的实现原理,它基于Java中的`AbstractQueuedSynchronizer`(AQS)构建,通过重写AQS的`tryAcquire`和`tryRelease`方法来实现锁的获取与释放,并详细描述了AQS内部的同步队列和条件队列以及独占模式的工作原理。
【多线程面试题十六】、谈谈ReentrantLock的实现原理
|
21天前
|
消息中间件 缓存 算法
Java多线程面试题总结(上)
进程和线程是操作系统管理程序执行的基本单位,二者有明显区别: 1. **定义与基本单位**:进程是资源分配的基本单位,拥有独立的内存空间;线程是调度和执行的基本单位,共享所属进程的资源。 2. **独立性与资源共享**:进程间相互独立,通信需显式机制;线程共享进程资源,通信更直接快捷。 3. **管理与调度**:进程管理复杂,线程管理更灵活。 4. **并发与并行**:进程并发执行,提高资源利用率;线程不仅并发还能并行执行,提升执行效率。 5. **健壮性**:进程更健壮,一个进程崩溃不影响其他进程;线程崩溃可能导致整个进程崩溃。
26 2
【多线程面试题十】、说一说notify()、notifyAll()的区别
notify()唤醒单个等待对象锁的线程,而notifyAll()唤醒所有等待该对象锁的线程,使它们进入就绪队列竞争锁。
|
21天前
|
存储 安全 容器
【多线程面试题二十一】、 分段锁是怎么实现的?
这篇文章解释了分段锁的概念和实现方式,通过将数据分成多个段并在每段数据上使用独立锁,从而降低锁竞争,提高并发访问效率,举例说明了`ConcurrentHashMap`如何使用分段锁技术来实现高并发和线程安全。
【多线程面试题二十一】、 分段锁是怎么实现的?
|
22天前
|
安全 Java
【多线程面试题十九】、 公平锁与非公平锁是怎么实现的?
这篇文章解释了Java中`ReentrantLock`的公平锁和非公平锁的实现原理,其中公平锁通过检查等待队列严格按顺序获取锁,而非公平锁允许新线程有更高机会立即获取锁,两者都依赖于`AbstractQueuedSynchronizer`(AQS)和`volatile`关键字以及CAS技术来确保线程安全和锁的正确同步。
【多线程面试题十九】、 公平锁与非公平锁是怎么实现的?
|
21天前
|
存储 缓存 安全
Java多线程面试题总结(中)
Java内存模型(JMM)定义了程序中所有变量的访问规则与范围,确保多线程环境下的数据一致性。JMM包含主内存与工作内存的概念,通过8种操作管理两者间的交互,确保原子性、可见性和有序性。`synchronized`和`volatile`关键字提供同步机制,前者确保互斥访问,后者保证变量更新的可见性。多线程操作涉及不同状态,如新建(NEW)、可运行(RUNNABLE)等,并可通过中断、等待和通知等机制协调线程活动。`volatile`虽不确保线程安全,但能确保变量更新对所有线程可见。
15 0
|
21天前
|
Java 程序员 容器
【多线程面试题二十四】、 说说你对JUC的了解
这篇文章介绍了Java并发包java.util.concurrent(简称JUC),它是JSR 166规范的实现,提供了并发编程所需的基础组件,包括原子更新类、锁与条件变量、线程池、阻塞队列、并发容器和同步器等多种工具。
|
21天前
|
缓存 Java
【多线程面试题二十三】、 说说你对读写锁的了解volatile关键字有什么用?
这篇文章讨论了Java中的`volatile`关键字,解释了它如何保证变量的可见性和禁止指令重排,以及它不能保证复合操作的原子性。
|
21天前
|
Java
【多线程面试题二十二】、 说说你对读写锁的了解
这篇文章讨论了读写锁(ReadWriteLock)的概念和应用场景,强调了读写锁适用于读操作远多于写操作的情况,并介绍了Java中`ReentrantReadWriteLock`实现的读写锁特性,包括公平性选择、可重入和可降级。