wait函数
wait函数是一个系统调用,用于等待一个子进程结束并回收其资源。当父进程调用wait函数时,它会暂停执行,直到至少有一个子进程结束。wait函数的原型如下:
cs
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
1.status参数是一个指针,用于存放子进程的退出状态信息。如果不需要检查子进程的退出状态,这个参数可以设置为NULL。
2.如果wait函数成功,它返回结束的子进程的进程ID。
3.如果调用wait函数的进程没有子进程结束,或者在等待期间被信号中断,wait函数返回-1
waitpid函数
waitpid函数提供了比wait更加灵活的接口,允许父进程等待特定的子进程结束,或者设置不同的等待选项。waitpid函数的原型如下:
cs
#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *status, int options);
1.pid参数指定了要等待的子进程的进程ID。
2.status参数是一个指针,用于存放子进程的退出状态值,退出状态值 只有最低8位有效 [0~255]
3.options参数可以包含不同的标志,用于控制waitpid的行为,例如WNOHANG使waitpid在没有子进程结束时立即返回,而不是等待。
4.waitpid函数在成功时返回等待的子进程的进程ID,失败时返回-1。
使用场景和差异
wait函数适用于简单的场景,即父进程等待任意一个子进程结束。而waitpid函数则适用于需要更多控制的场景,例如等待特定的子进程、等待进程组中的任一子进程或所有子进程,或者在不阻塞父进程的情况下进行等待。
waitpid函数的options参数提供了额外的灵活性,使得父进程可以根据需要调整等待行为。例如,使用WNOHANG选项可以避免父进程在没有子进程结束时被阻塞,这在编写交互式程序时非常有用。
在实际应用中,开发者应该根据具体的进程管理需求选择合适的函数。如果需要等待所有子进程结束并重拾资源,wait函数通常足够使用。如果需要更精细的控制,waitpid函数则是更好的选择。
线程
线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。一个进程可以拥有多个线程,这些线程共享进程的资源(如内存空间),但每个线程有自己的寄存器和局部变量。
线程的关键特点:
1.轻量级:线程之间的切换比进程之间的切换要轻量级,因为线程共享同一进程的资源,不需要进行系统调用,所以线程的创建和销毁成本较低。
2.共享资源:同一进程内的线程共享进程的数据空间,这意味着它们可以访问相同的全局变量和文件句柄。这在需要线程间通信时非常便捷,但同时也需要小心处理并发访问,以避免数据不一致或死锁问题。
3.并发执行:线程可以并发执行,这意味着在多核处理器系统中,不同的线程可以在不同的处理器核心上同时运行,从而提高应用程序的执行效率。
线程与进程的关系
1.区别:线程是操作系统调度的基本单元,而进程是资源分配的基本单元。进程之间是独立的,有独立的地址空间;而线程之间共享同一进程的地址空间和资源,通信更直接和快速。
2.联系:线程是进程的一部分,一个进程可以拥有多个线程,所有线程共享进程的资源,但每个线程有自己的执行栈和寄存器。
pthread_create函数
pthread_create函数是用于在POSIX兼容的系统中创建新线程的标准库函数。它定义在<pthread.h>头文件中,并允许用户指定线程的属性、启动函数以及传递给该函数的参数。
函数原型
cs
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg);
参数解释
1.thread:指向pthread_t类型变量的指针,该变量将接收新创建线程的ID。
2.attr:指向pthread_attr_t类型变量的指针,用于设置线程的属性,如堆栈大小、调度策略等。如果不需要特殊设置,可以传递NULL以使用默认属性。
3.start_routine:指向线程执行函数的指针,该函数的原型为void *(*start_routine)(void *),即接受一个void *类型的参数并返回一个void *类型的值。
4.arg:传递给线程执行函数的参数,类型为void *。
返回值
1.如果线程创建成功,返回0。
2.如果创建失败,返回错误代码。
pthread_exit函数
pthread_exit函数用于正常结束一个线程,并可以设置线程结束时的返回值。当一个线程调用pthread_exit时,它立即停止执行,并将控制权返回给线程调度器。如果pthread_exit的参数不是NULL,该值将作为线程的返回状态传递给任何后续调用pthread_join的线程。
函数原型
cs
void pthread_exit(void *retval);
参数解释
1.retval:指向要传递给pthread_join的线程返回值的指针。如果线程结束时不需要传递返回值,可以传递NULL。
返回值
pthread_exit函数本身没有返回值,因为它用于结束当前线程的执行。
使用场景
pthread_exit通常在以下情况下使用:
1.当线程完成了其任务,需要立即结束时。
2.当线程遇到错误或异常情况,需要提前退出时。
pthread_join函数
pthread_join函数用于等待一个特定的线程结束,并从该线程中检索其返回值。这个函数是线程间同步的一种机制,可以确保主线程或其他线程在继续执行之前等待某个线程完成其工作。
函数原型
cs
int pthread_join(pthread_t thread, void **retval);
参数解释
1.thread:待等待结束的线程的ID。
2.retval:指向变量的指针,用于存储被等待线程的返回值。如果不需要获取返回值,可以传递NULL。
返回值
1.如果函数成功,返回0。
2.如果发生错误,返回相应的错误码。
使用场景
pthread_join通常用于以下场景:
1.当主线程需要等待子线程完成任务并获取结果时。
2.当需要确保某个线程在程序的其他部分之前完成执行时。
cs
#include<stdio.h>
#include <pthread.h>
void *str1(void *arg)
{
static char *s = "Hello World!";
puts(s);
pthread_exit(s);
}
int main(void)
{
pthread_t tid;
int ret = pthread_create(&tid,NULL,str1,NULL);
void *retid;
pthread_join(tid,&retid);
printf("exit = %s\n",(char *)retid);
return 0;
}