嵌入式学习(day 28)线程

1、回收资源空间:wait() 与 waitpid()

僵尸进程(Zombie Process):

定义:进程退出后,其资源空间尚未被父进程回收的状态。

特点:

  • 进程已终止,但仍在进程表中保留条目

  • 占用少量系统资源(如 PID),但不消耗 CPU 和内存

  • 无法被杀死,必须由父进程回收

如何避免僵尸进程产生?

  1. 父进程及时调用 wait() 或 waitpid() 回收子进程资源

  2. 让子进程成为孤儿进程(Orphan Process),由系统自动回收

#include <sys/types.h>

#include <sys/wait.h>

pid_t wait(int *wstatus);

阻塞等待并回收任意一个已终止的子进程资源。

该函数会暂停父进程,直到某个子进程结束。

参数:

wstatus:指向整型变量的指针,用于保存子进程退出状态

若不关心退出状态,可设为 NULL

返回值:

成功:返回被回收的子进程的 PID

失败:返回 -1(通常表示没有子进程或系统错误)

wait(NULL); // 不关心退出状态,仅回收子进程资源

2、 pid_t waitpid(pid_t pid, int *status, int options); (了解)

回收指定进程的资源。 与 wait 功能相似,但比 wait 更灵活,可以指定等待哪个子进程。

参数说明:pid:指定要等待的子进程 ID

< -1:回收指定进程组内的任意子进程(例如:-100 表示等待 GID=100 的进程组中的任意子进程)

= -1:回收任意子进程(不限于当前进程组)

= 0:回收与当前调用 waitpid 的进程同属一个组的所有子进程

> 0:回收指定 PID 的子进程

status:指向整型变量的指针,用于保存子进程退出状态

如果不关心退出状态,可设为 NULL

options:选项标志

0:表示阻塞等待(默认)

WNOHANG:非阻塞模式,若没有子进程退出则立即返回

返回值:

成功:返回被回收的子进程的 PID

失败:返回 -1

若设置 WNOHANG 且无子进程可回收:返回 0

子进程资源空间回收策略:

(1) wait 阻塞回收:父进程调用 wait() 阻塞等待子进程结束

(2)waitpid 非阻塞方式回收:使用 waitpid() 并设置 options 为 WNOHANG 实现非阻塞,父进程可在循环中轮询检查是否有子进程退出

(3)不回收:子进程任务需一直执行

(4)异步回收:使用信号机制(如 SIGCHLD)通知父进程子进程已结束

3、exec:函数族

在一个进程里面执行另外一个文件(可执行文件):

本质:将文本去的指令代码替换为 exec 要执行的文件的指令。

int execl(const char *path, const char *arg, ... /* (char *) NULL */);

参数:

path:要执行的可执行文件的路径和名称

arg:执行该可执行文件时需要传递的参数

NULL:参数传递结束标志

返回值:

出错:-1

int execlp(const char *file, const char *arg, ... /* (char *) NULL */);

功能:从 PATH 指定的系统路径下寻找该可执行文件

参数:

file:需要执行的可执行文件的名称(系统路径下已有的文件)

arg:执行该可执行文件时需要传递的参数

int execle(const char *path, const char *arg, ... /*, (char *) NULL, char * const envp[] */);

int execv(const char *path, char *const argv[]);

int execvp(const char *file, char *const argv[]);

int execvpe(const char *file, char *const argv[], char *const envp[]);

4、线程:

(1) 什么是线程

轻量级的进程,可实现多任务的并发。

进程是操作系统资源分配的最小单位;

线程是操作系统任务调度的最小单位。

(2)线程的创建

线程由某个进程创建。

进程创建线程时,会为其分配独立的(8M)栈区空间;

线程和所在进程,以及进程中的其他线程,共用进程的堆区、数据区、文本区。

(3)线程的调度:宏观并行,微观串行

(4)线程消亡

  1. 线程退出

  2. 回收线程资源空间

(5)进程和线程的区别:

进程:

  • 进程是操作系统资源分配的最小单位;

  • 资源消耗:进程资源开销大,每次创建都需要有 0-4G 的虚拟内存空间;

  • 效率角度:由操作系统创建,创建时耗时比线程大;跨进程调度比跨线程调度慢;

  • 通信方面:进程间不能直接通信,需要使用进程间通信机制(IPC 机制);

  • 安全性角度:进程安全性比线程高,各进程空间独立。

线程:

  • 线程是操作系统任务调度的最小单位;

  • 资源消耗:资源开销较小,只需要所在进程为其开辟 8M 的栈区空间;

  • 效率角度:由所在进程创建;跨进程调度比跨线程调度慢;

  • 通信方面:通信简单,可以使用线程共享的区域进行通信(比如全局变量);

  • 安全性角度:线程没有进程安全性好,一个线程异常可能影响同一进程中的所有线程。

(6) 线程的相关编程

线程的创建:pthread_create()

pthread_self():获取当前线程的ID号

线程调度:由操作系统调度

线程消亡:

  1. 线程退出:pthread_exit();

  2. 线程回收:pthread_join();

#include <pthread.h>

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,

void *(*start_routine)(void *), void *arg);

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,

void *(*start_routine)(void *), void *arg);

参数:

thread:保存线程ID的变量地址

attr:线程属性的对象地址

NULL:按照默认属性创建

start_routine:函数的指针:指向线程启动后要执行的任务(线程任务函数)

arg:为线程任务函数传递的参数

返回值:

成功:0

失败:非0

相关推荐
没有bug.的程序员2 小时前
JVM 总览与运行原理:深入Java虚拟机的核心引擎
java·jvm·python·虚拟机
星星火柴9363 小时前
关于“双指针法“的总结
数据结构·c++·笔记·学习·算法
小狗爱吃黄桃罐头3 小时前
正点原子【第四期】Linux之驱动开发篇学习笔记-1.1 Linux驱动开发与裸机开发的区别
linux·驱动开发·学习
艾莉丝努力练剑4 小时前
【洛谷刷题】用C语言和C++做一些入门题,练习洛谷IDE模式:分支机构(一)
c语言·开发语言·数据结构·c++·学习·算法
武昌库里写JAVA5 小时前
JAVA面试汇总(四)JVM(一)
java·vue.js·spring boot·sql·学习
杜子不疼.6 小时前
《Python学习之字典(一):基础操作与核心用法》
开发语言·python·学习
小幽余生不加糖6 小时前
电路方案分析(二十二)适用于音频应用的25-50W反激电源方案
人工智能·笔记·学习·音视频
..过云雨7 小时前
01.【数据结构-C语言】数据结构概念&算法效率(时间复杂度和空间复杂度)
c语言·数据结构·笔记·学习
myzzb7 小时前
基于uiautomation的自动化流程RPA开源开发演示
运维·python·学习·算法·自动化·rpa