进程
wait函数
功能
- 等待子进程结束:父进程调用
wait
函数后,会暂停执行,直到它的某个子进程结束。 - 收集子进程状态:当子进程结束时,
wait
函数会返回子进程的终止状态,包括是正常终止还是被信号终止等信息。
wait
函数的基本原型如下:
#include <sys/types.h> |
#include <sys/wait.h> |
pid_t wait(int *status); |
参数:status
是一个指向整数的指针,用来存储子进程的退出状态。如果不需要这个状态,可以传入NULL
。- 返回值:成功时,返回结束的子进程的PID;出错时,返回-1,并设置errno以指示错误。
注意事项
wait
函数只等待一个子进程结束,如果有多个子进程,它会返回最先结束的那个子进程的PID。- 如果所有子进程都已经结束,
wait
函数会立即返回-1,并设置errno为ECHILD
。 - 为了避免僵尸进程(已结束但父进程未通过
wait
等函数回收其资源的子进程),父进程应该及时调用wait
或相关函数来回收子进程资源。 - 在多线程程序中,使用
wait
函数可能需要考虑线程同步问题,因为wait
函数会阻塞调用它的线程。
waitpid
#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *status, int options);
参数说明
-
pid:指定要等待的子进程的PID。它有几个特殊的值:
> 0
:等待指定PID的子进程。0
:等待与调用进程属于同一进程组的任何子进程。-1
:等待任何子进程,与wait
函数相似。< -1
:等待其组ID等于pid的绝对值的任何子进程。
-
status:用于存储子进程的退出状态。如果不需要,可以设置为
NULL
。 -
options:控制
waitpid
的行为。它可以是0,表示默认行为(阻塞等待),或者使用以下选项的组合(通过|
运算符连接):WNOHANG
:非阻塞模式。如果指定的子进程没有结束,则返回0而不是阻塞等待。WUNTRACED
:报告子进程的停止状态(比如,被信号暂停)。WCONTINUED
:如果子进程因为被SIGCONT信号唤醒而产生了SIGCHLD信号,则立即返回。
返回值
- 成功时,返回结束的子进程的PID。
- 如果设置了
WNOHANG
且没有子进程结束,则返回0。 - 出错时,返回-1,并设置errno以指示错误。
非阻塞和阻塞
阻塞:会阻塞父进程处理逻辑
非阻塞:父进程会去查看子进程状态改变,但是 如果没有发生改变,父进程不阻塞,整个程序继续往下。非阻塞必须套在循环中处理
线程
线程是计算机科学中的基本概念,指的是在一个进程中执行的独立指令流。以下是对线程的详细解释:
一、定义与特性
- 定义:线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。一个进程中可以并发多个线程,每条线程并行执行不同的任务。
- 特性:
- 独立调度和分派的基本单位:在多线程操作系统中,线程是能独立运行的基本单位,因而也是独立调度和分派的基本单位。
- 可并发执行:一个进程中的多个线程可以并发执行,甚至允许在一个进程中所有线程都能并发执行,同时,不同进程中的线程也能并发执行。
- 共享进程资源:同一进程中的各个线程都可以共享该进程所拥有的资源,如内存空间、文件句柄等,但每个线程又有自己的独立执行流和调用栈。
二、组成与结构
- 线程由线程标识符、程序计数器、寄存器集合和堆栈组成。其中,线程标识符用于唯一标识一个线程;程序计数器用于指示线程当前执行的指令地址;寄存器集合用于存储线程执行过程中需要的各种数据;堆栈则用于存储线程调用函数时的局部变量和返回地址等。
三.为什么需要线程?
线程 --- 轻量级的进程
进程 --- 重量级的进程
线程 成为 CPU执行的最小单位
进程 成为 资源分配的基本单位
线程
创建 和 调度 时空开销都比进程小
四. 线程与进程的关系
a.线程 是 存在于 进程中的
b.线程 共享了进程的资源 (代码段,数据段,打开一些文件,信号等)
c.线程结束,不一定导致进程结束
五.线程的编程
类似与进程过程
线程函数
Red hat / IBM
//thinkpad
ubuntu
contos //服务器上 --- linux系统运维
red hat 实现的一套线程函数 //NPTL线程库
NPTL (New Posix Thread Library)
a.线程的创建
pthread_create
int pthread_create(pthread_t *thread,
const pthread_attr_t *attr,
void *(*start_routine) (void *),
void *arg);
功能:该函数可以创建指定的一个线程。
参数:
@thread 线程id,需要实现定义并由该函数返回。
@attr 线程属性,一般是NULL,表示默认属性。(可结合性+分离属性)
默认(可结合性) -- 自己手动回收
分离属性 -- 系统自动回收
@start_routine -- 线程执行函数 (线程回调函数)
//指向[指针函数的] 函数指针。
本质上是一个函数的名称即可。
称为
th 回调函数,是线程的执行空间。
{
}
//注: 线程回调函数 --完成线程任务功能的函数
// 需要调用者 自己实现
@arg 回调函数的参数,即参数3的指针函数参数。
返回值:成功 0
失败 错误码
获得线程tid:
pthread_self(); //在那个线程中调用,获得的就是那个线程的tid
b.线程的执行
就体现在线程的 执行函数(回调函数)上
c.线程的退出
方式1
pthread_exit
void pthread_exit(void *retval)
功能:
结束调用的线程
参数:
@retval //退出状态值 //传的是,退出状态值 对应的地址
注意:
1.pthread_exit 本身表示结束线程 如果用在main函数中 表示结束主线程 主线程结束 并不表示程 此时,主线程执行流结束,进程会在其余线程都结束后,结束
d.线程的资源回收
int pthread_join(pthread_t thread, void **retval);
功能:
等待线程结束
参数:
@thread --- 线程tid
@retval --- 用来保存,退出状态值,所在空间的地址
返回值:
成功 0
失败 错误码
注:
线程退出时,可以带出退出状态值,但是传的是,退出状态值对应空间的地址