电子商务网站建设与营运,免费erp系统,用jsp做的购物网站,wordpress core主题一、线程的核心概论在 Linux 系统中#xff0c;线程是轻量级的进程#xff0c;它并非独立存在#xff0c;而是隶属于某个进程。一个进程可以包含多个线程#xff0c;这些线程共享进程的大部分资源#xff08;如代码段、数据段、打开的文件描述符等#xff09;#xff0c…一、线程的核心概论在 Linux 系统中线程是轻量级的进程它并非独立存在而是隶属于某个进程。一个进程可以包含多个线程这些线程共享进程的大部分资源如代码段、数据段、打开的文件描述符等同时拥有自己独立的执行上下文。线程的核心作用和进程一致都是为了实现并发执行尤其适用于处理相对耗时的任务。比如在一个网络服务程序中主线程负责监听客户端连接子线程负责处理每个客户端的请求这种多线程模型可以大幅提升程序的响应效率。二、线程与进程的核心区别理解线程的关键是厘清它与进程的核心差异 —— 这也是线程所有特性的根源具体可从以下维度对比维度进程线程资源分配单位系统最小资源分配单位系统最小执行单位资源归属拥有独立的 3GB 用户空间资源完全独立共享所属进程资源仅独立拥有 8MB 栈区稳定性进程崩溃不影响其他进程稳定性高单个线程崩溃会导致整个进程崩溃稳定性低创建开销需分配完整 3GB 空间开销极大仅开辟 8MB 栈区开销远低于进程并发能力创建 / 切换开销大并发度低创建 / 切换开销小并发度远高于进程2.1 资源共享与独立性进程资源完全对立每个进程拥有独立的地址空间、文件描述符、全局变量等进程间无法直接访问彼此资源需通过管道、共享内存等 IPC 机制通信。线程同一进程内的线程共享绝大部分资源代码段、数据段、堆区、全局变量、打开的文件等仅栈区独立每个线程有专属 8MB 栈区存储局部变量和函数调用栈。这种特性让线程间通信成本极低但也要求编程时注意资源竞争问题。2.2 稳定性差异进程是操作系统独立的资源分配单元一个进程的崩溃如段错误只会释放自身资源不会影响其他进程而线程共享进程的资源空间若某个线程触发内存非法访问等错误操作系统会终止整个进程导致所有线程一同退出。2.3 创建开销与并发度创建开销新建进程需要完整分配 3GB 用户空间涉及页表、资源拷贝等大量操作新建线程仅需在进程已有空间内开辟 8MB 栈区几乎无额外资源分配成本。并发度线程的创建和上下文切换开销远小于进程系统可同时调度成百上千个线程而进程数量受限于内存和系统资源因此线程的并发能力远高于进程。2.4 执行与层级特性补充说明线程的核心执行特征进程中的所有线程为平级关系无父子线程之分每个进程默认包含一个主线程main函数运行在主线程中。进程是 “资源容器”线程是容器内的 “执行流”—— 没有进程的资源支撑线程无法独立存在没有线程进程只是一个静态的资源集合无法执行任何逻辑。三、Linux 下查看线程信息的命令在 Linux 中我们可以通过以下命令查看线程的运行状态这对调试多线程程序非常有帮助ps -eLo pid,ppid,lwp,stat,comm该命令可以查看系统中所有线程的关键信息各字段含义如下pid线程所属进程的 IDppid进程的父进程 IDlwp线程的 ID轻量级进程 IDstat线程的运行状态comm线程对应的命令名称ps -eLf该命令会以更详细的格式列出所有线程的信息包括线程的优先级、CPU 占用时间等。四、POSIX 线程编程步骤与核心函数Linux 下的线程编程遵循 POSIX 标准对应的线程库为pthread编程的核心步骤为创建多线程 → 线程空间操作 → 线程资源回收。下面逐一介绍核心函数的使用方法并为每个函数提供独立的可运行示例代码。4.1 线程创建pthread_create函数说明#include pthread.h int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);功能创建一个新的线程参数说明thread指向pthread_t类型变量的指针用于存储新创建线程的 ID由函数返回。attr线程属性一般设为NULL表示使用默认属性。start_routine函数指针指向线程的执行函数回调函数该函数的返回值和参数均为void*类型是线程的核心执行逻辑。arg传递给回调函数start_routine的参数。返回值成功返回 0失败返回对应的错误码。独立示例代码#include stdio.h #include pthread.h #include string.h #include unistd.h // 线程执行函数 void *thread_func(void *arg) { char *msg (char *)arg; printf(子线程ID%lu接收参数%s\n, pthread_self(), msg); sleep(2); // 模拟线程执行耗时操作 printf(子线程执行完成\n); return NULL; } int main() { pthread_t tid; char *msg Hello Thread; // 创建线程 int ret pthread_create(tid, NULL, thread_func, msg); if (ret ! 0) { printf(创建线程失败%s\n, strerror(ret)); return -1; } printf(主线程创建线程成功线程ID%lu\n, tid); sleep(3); // 主线程等待子线程执行完成 printf(主线程执行完成\n); return 0; }编译运行gcc pthread_create_demo.c -o pthread_create_demo -lpthread ./pthread_create_demo4.2 获取线程 IDpthread_self函数说明#include pthread.h pthread_t pthread_self(void);功能获取当前线程的 ID参数无返回值成功返回当前线程的 ID类型为pthread_t可通过%lu格式符打印失败返回非 0 值。独立示例代码#include stdio.h #include pthread.h #include unistd.h void *thread_func(void *arg) { // 获取子线程ID pthread_t tid pthread_self(); printf(子线程自身ID %lu\n, tid); return NULL; } int main() { pthread_t tid; // 创建线程 pthread_create(tid, NULL, thread_func, NULL); // 获取主线程ID printf(主线程自身ID %lu\n, pthread_self()); printf(主线程创建的子线程ID %lu\n, tid); sleep(1); // 等待子线程执行 return 0; }编译运行gcc pthread_self_demo.c -o pthread_self_demo -lpthread ./pthread_self_demo4.3 线程退出pthread_exit函数说明#include pthread.h void pthread_exit(void *retval);功能子线程自行退出参数retval线程退出时的返回状态可被后续的资源回收函数获取。返回值无独立示例代码#include stdio.h #include pthread.h #include unistd.h void *thread_func(void *arg) { printf(子线程开始执行准备退出\n); sleep(2); // 定义退出返回值 int *ret (int *)malloc(sizeof(int)); *ret 99; // 线程退出传递返回值 pthread_exit((void *)ret); } int main() { pthread_t tid; void *ret_val; pthread_create(tid, NULL, thread_func, NULL); // 等待子线程退出并回收资源 pthread_join(tid, ret_val); printf(主线程子线程退出返回值 %d\n, *(int *)ret_val); free(ret_val); // 释放子线程分配的内存 return 0; }编译运行gcc pthread_exit_demo.c -o pthread_exit_demo -lpthread ./pthread_exit_demo4.4 线程取消pthread_cancel函数说明#include pthread.h int pthread_cancel(pthread_t thread);功能请求结束一个指定的线程参数thread需要被取消的线程的 ID返回值成功返回 0失败返回非 0 值。独立示例代码#include stdio.h #include pthread.h #include unistd.h #include string.h void *thread_func(void *arg) { printf(子线程开始执行进入循环\n); // 线程设置为可取消默认状态 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); // 设置取消类型为立即取消接收到取消信号后立即退出 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); while (1) { sleep(1); printf(子线程循环执行中...\n); } return NULL; } int main() { pthread_t tid; pthread_create(tid, NULL, thread_func, NULL); // 主线程等待3秒后取消子线程 sleep(3); int ret pthread_cancel(tid); if (ret ! 0) { printf(取消线程失败%s\n, strerror(ret)); return -1; } printf(主线程已发送取消线程的请求\n); // 回收子线程资源 pthread_join(tid, NULL); printf(主线程子线程已被取消并回收\n); return 0; }编译运行gcc pthread_cancel_demo.c -o pthread_cancel_demo -lpthread ./pthread_cancel_demo4.5 线程资源回收pthread_joinvspthread_detach线程退出后其栈区等资源不会默认释放必须通过特定方式回收。pthread_join和pthread_detach是两种核心回收方式二者核心区别如下特性pthread_joinpthread_detach执行方式阻塞式等待目标线程退出后才返回非阻塞式设置属性后立即返回资源回收时机线程退出后由调用方主动回收线程退出后由系统自动回收退出状态获取可通过retval获取线程退出状态无法获取线程退出状态调用限制只能被一个线程调用重复调用会报错仅需调用一次线程退出后自动生效适用场景需要获取线程执行结果、需同步等待线程结束无需获取线程结果、希望异步释放资源4.5.1pthread_join阻塞式回收函数说明#include pthread.h int pthread_join(pthread_t thread, void **retval);功能回收指定线程的资源并获取线程的退出状态参数说明thread需要回收的子线程的 IDretval指向void*类型的指针用于存储线程的退出状态即pthread_exit传递的参数返回值成功返回 0失败返回非 0 值。独立示例代码#include stdio.h #include pthread.h #include unistd.h #include string.h void *thread_func(void *arg) { int num *(int *)arg; printf(子线程接收参数 %d开始执行\n, num); sleep(3); // 模拟耗时操作 // 退出并返回计算结果 int *ret malloc(sizeof(int)); *ret num * 2; pthread_exit((void *)ret); } int main() { pthread_t tid; int arg 10; void *ret_val; // 创建线程 int ret pthread_create(tid, NULL, thread_func, arg); if (ret ! 0) { printf(创建线程失败%s\n, strerror(ret)); return -1; } printf(主线程等待子线程执行完成...\n); // 阻塞回收子线程获取返回值 ret pthread_join(tid, ret_val); if (ret ! 0) { printf(回收线程失败%s\n, strerror(ret)); return -1; } printf(主线程子线程回收成功返回值 %d\n, *(int *)ret_val); free(ret_val); // 释放内存 return 0; }编译运行gcc pthread_join_demo.c -o pthread_join_demo -lpthread ./pthread_join_demo4.5.2pthread_detach分离式回收函数说明#include pthread.h int pthread_detach(pthread_t thread);功能设置线程的分离属性参数thread需要设置分离属性的线程的 ID可以是当前线程如pthread_detach(pthread_self())返回值成功返回 0失败返回非 0 值。独立示例代码#include stdio.h #include pthread.h #include unistd.h #include string.h void *thread_func(void *arg) { // 为当前线程设置分离属性 int ret pthread_detach(pthread_self()); if (ret ! 0) { printf(子线程设置分离属性失败%s\n, strerror(ret)); pthread_exit(NULL); } printf(子线程已设置分离属性开始执行\n); sleep(2); printf(子线程执行完成即将退出资源会被系统自动回收\n); pthread_exit(NULL); } int main() { pthread_t tid; // 创建线程 int ret pthread_create(tid, NULL, thread_func, NULL); if (ret ! 0) { printf(创建线程失败%s\n, strerror(ret)); return -1; } printf(主线程创建分离线程成功ID %lu\n, tid); // 尝试join分离线程会失败 ret pthread_join(tid, NULL); if (ret ! 0) { printf(主线程尝试join分离线程失败预期结果%s\n, strerror(ret)); } // 主线程等待子线程执行完成 sleep(3); printf(主线程程序执行结束\n); return 0; }编译运行gcc pthread_detach_demo.c -o pthread_detach_demo -lpthread ./pthread_detach_demo五、总结线程作为 Linux 下的轻量级进程凭借其低开销、高并发的特性成为实现并发程序的重要工具。与进程相比线程共享进程资源仅栈区独立、创建开销仅为开辟 8MB 栈区进程需 3GB 空间、并发度更高但稳定性更弱 —— 单个线程崩溃会导致整个进程退出。在 POSIX 线程编程中每个核心函数都有明确的定位pthread_create是线程创建的入口需指定执行函数和参数pthread_self用于获取线程自身 ID便于调试和线程标识pthread_exit让线程主动退出并传递返回值pthread_cancel可被动终止线程pthread_join阻塞回收适合需要获取线程执行结果的场景pthread_detach分离回收适合无需同步等待的场景。