Part 1 程序 进程 线程之间的区别 进程的几种状态

一. 程序 进程 线程的概念
程序是一个静态文件的描述,不占有计算机的系统资源。
进程是一个动态的过程,占有CPU内存等资源,有一定的生命周期。

同一个程序的不同执行过程即为不同的进程。

线程有称为轻量级进程,在并发上和进程相同但是在创建时消耗资源少,
一个进程中可以包含多个线程,这多个线程共享进程资源。

二. 进程和线程的区别
(1)多进程和多线程都是多任务编程方式,都可以使用计算机多核。
(2)进程的创建要比线程消耗更多资源。
(3)进程空间独立数据更安全,有专门的进程间通信方式进行交互。
(4)一个进程包含多个线程,所以线程共享进程资源,没有专门的通信方法,
依赖全局变量进行通信。往往需要使用同步互斥机制,需要考虑更多的逻辑。

三 .进程的几种状态
(1)三态
1.就绪态:进程具有运行条件,等待系统分派处理器以便运行。
2.运行态:进程占有CPU处于运行状态。
3.等待态:又称为阻塞态或者睡眠态,指进程不具备运行条件,正在等待某些条件的达成)。
在这里插入图片描述
(2)五态
1.就绪态:进程具有运行条件,等待系统分派处理器以便运行。
2.运行态:进程占有CPU处于运行状态。
3.等待态:又称为阻塞态或者睡眠态,指进程不具备运行条件,正在等待某些条件的达成。
4.新建态:创建一个进程的过程,直接表现为执行某个程序或者在程序中创建新的进程。
5.终止态:进程执行结束,完成回收的过程)。
在这里插入图片描述

(3)几个问题
1.什么决定了进程的创建
用户通过应用层程序进程进程的创建申请。
调用操作系统接口进行进程创建。
告知系统内核创建新的进程提供给应用层使用。
2.进程如何占有CPU
同一个内核同一个时刻只能运行一个进程。
多个进程对内核资源进行抢占,由操作系统内核进行分配。
哪个进程占有计算机内核我们称该进程占有CPU的时间片。
3.进程在运行过程中的形态和附带内容
PCB(进程控制块):中linux和unix操作系统中,进程创建后会在内存中
开辟一块空间存放进程的相关信息,这个空间称为PCB。
PID:在操作系统中进程的唯一标识,是一个大于0的正整数,由系统自动分配。

### 线程 `join` 方法的使用方法及作用 #### 1. **线程 `join` 的基本概念** 线程的 `join` 方法用于使当前线程等待另一个线程完成后再继续执行。这意味着如果某个线程 A 调用了线程 B 的 `join()` 方法,则线程 A 将会暂停执行,直到线程 B 执行完毕[^1]。 #### 2. **线程 `join` 的语法结构** 在 Java 和 Python 中,`join` 方法的具体实现略有不同: - **Java 实现** 在 Java 中,`join` 是 `Thread` 类的一个方法,其定义如下: ```java public final void join() throws InterruptedException { ... } ``` 此外还有带参数版本可以指定最大等待时间: ```java public final synchronized void join(long millis) throws InterruptedException { ... } ``` - **Python 实现** 在 Python 中,`join` 同样是一个线程对象的方法,其默认行为也是阻塞调用者直至目标线程结束: ```python thread.join(timeout=None) ``` 参数 `timeout` 可选,表示最多等待的时间(单位为秒),超时后即使线程未结束也会返回[^2]。 #### 3. **线程 `join` 的具体作用** ##### (1) **同步多个线程的执行顺序** 通过 `join` 方法,开发者能够控制程序中各线程之间的依赖关系。例如,在某些场景下需要确保几个并行任务全部完成后才能进行下一步操作,这时可以通过连续调用这些线程的 `join` 方法来达成目的。 ##### (2) **防止资源竞争和数据不一致** 在线程间共享资源的情况下,合理安排线程启动停止时机有助于减少竞态条件的发生概率。利用 `join` 让父进程或主线程知道何时安全地访问由子线程产生的结果[^3]。 ##### (3) **简化调试过程** 由于加入了显式的等待机制,因此更容易追踪各个阶段的任务进展状况以及定位潜在错误所在位置[^4]。 #### 4. **实际应用案例分析** 以下是分别基于两种编程语言展示如何运用 `join` 功能的一组简单实例代码片段: - **Java 版本示例** 假设有三个独立工作的线程 t1, t2 和 t3 ,我们希望它们按创建次序依次运行结束后才打印最终消息 “All threads have finished.” : ```java class MyTask extends Thread { private String name; public MyTask(String n){ this.name=n; } @Override public void run(){ System.out.println(name+" is running..."); try{ sleep((int)(Math.random()*5000)+1000); //模拟耗时工作 }catch(Exception e){e.printStackTrace();} System.out.println(name+" has completed."); } } public static void main(String[] args)throws Exception{ MyTask t1=new MyTask("T1"); MyTask t2=new MyTask("T2"); MyTask t3=new MyTask("T3"); t1.start();t2.start();t3.start(); t1.join();t2.join();t3.join(); System.out.println("All threads have finished."); } ``` - **Python 版本示例** 下面这段脚本展示了类似的功能但是采用的是 python threading 库构建而成: ```python import time from threading import Thread def task_func(thread_name,delay): print(f"{thread_name} starts working...") time.sleep(delay)#Simulate workload duration. print(f"{thread_name} finishes its job.") if __name__=='__main__': th_list=[] delays=[random.uniform(1,5)for _ in range(3)] names=["WorkerA","WorkerB","WorkerC"] for i,name in enumerate(names): worker=Thread(target=task_func,args=(name,int(delays[i]))) th_list.append(worker) worker.start() for wkr in th_list: wkr.join() print('Every single one of them done their part.') ``` 上述两段代码均体现了通过 `join` 达成多线程协作的效果——即只有当所有参计算的小型单元都宣告成功之后才会触发全局性的通知动作. #### 5. **注意事项** 尽管 `join` 提供了一种便捷的方式来协调并发流程间的交互模式,但在实际项目开发过程中仍需注意以下几点事项以免引入不必要的复杂度或者性能瓶颈: - 过量频繁地调用可能会降低整体吞吐率因为增加了额外开销; - 当存在循环依赖的时候容易造成死锁现象发生所以设计初期就应该规避此类风险; - 对于长时间运行的大规模分布式系统来说可能考虑其他更高效的通信方式代替传统意义上的直接连接形式; ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值