一、
Linux系统中的多线程编程是现代软件开发中不可或缺的一部分,线程作为程序执行的最小单位,能够有效提高程序的并发性和效率,本文将详细介绍在Linux环境下如何进行线程分离编程,包括其定义、目的、方法以及常见问题的解决方案。
二、线程的基本概念与区别
进程与线程的区别
进程:分配资源(内存)的最小单位,有独立的 进程地址空间,有独立的pcb。
线程:程序执行的最小单位,没有独立的进程地址空间,有独立的pcb,每一个进程由一个或多个线程组成,至少有一个主线程。
线程之间的资源共享
独享:栈空间(内核栈、用户栈)
共享:/text ./data ./rodata ./bsss heap 全局变量
线程ID
每个线程都有自己的ID,可以通过pthread_self()
函数获取当前线程的ID。
三、线程创建与回收
线程创建
使用pthread_create()
函数创建一个新线程,其原型如下:
int pthread_create(pthread_t *tid, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
pthread_t *tid
:传出参数,新创建的线程id
const pthread_attr_t *attr
:线程属性(一般设为NULL)
void *(*start_routine)(void *)
:子线程回调函数
void *arg
:回调函数的参数
返回值:成功返回0,失败返回错误码。
示例代码:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <string.h> void *thread_fun(void *argc) { //回调函数,子线程执行的函数 printf("new tread "); return NULL; } int main(int argc,char*argv[]){ int ret; pthread_t tid; ret = pthread_create(&tid, NULL, thread_fun, NULL); //创建子线程 if (ret != 0) { printf("create failed "); exit(1); } sleep(1); //等待子线程运行完 printf("mian thread "); return 0; }
输出结果:
new tread mian thread
线程回收
2.1 线程连接(Joining)
使用pthread_join()
函数等待某线程的退出并接收它的返回值。
int pthread_join(pthread_t thread, void **retval);
thread
:待回收的线程id
retval
:传出参数,用来接收线程返回值
返回值:成功返回0,失败返回错误码。
示例代码:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <string.h> void *thread_fun(void *argc) { //回调函数,子线程执行的函数 sleep(5); printf("new thread sleep 5s "); return NULL; } int main(int argc,char*argv[]){ int ret; pthread_t tid; ret = pthread_create(&tid, NULL, thread_fun, NULL); //创建子线程 if (ret != 0) { printf("create failed "); } pthread_join(tid, NULL); //主线程阻塞 printf("main thread "); return 0; }
运行结果:
new thread sleep 5s main thread
2.2 线程分离(Detaching)
默认情况下,新创建的线程处于可连接状态,需要通过pthread_join()
来等待其结束并释放资源,如果不关心线程的返回值,可以使用pthread_detach()
将线程设置为分离状态,系统会自动回收其资源。
int pthread_detach(pthread_t thread);
thread
:要分离的线程ID。
返回值:成功返回0,失败返回错误码。
示例代码:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <string.h> void *thread_fun(void *argc) { //回调函数,子线程执行的函数 printf("new tread "); return NULL; } int main(int argc,char*argv[]){ int ret; pthread_t tid; ret = pthread_create(&tid, NULL, thread_fun, NULL); //创建子线程 if (ret != 0) { printf("create failed "); exit(1); } pthread_detach(tid); //设置线程为分离状态 sleep(1); //等待子线程运行完 printf("mian thread "); return 0; }
运行结果:
new tread mian thread
3 杀死线程函数
在某些情况下,可能需要提前终止一个线程,可以使用pthread_cancel()
函数,但需要注意的是,被取消的线程必须有一个取消点(例如系统调用),否则无法被真正终止。
int pthread_cancel(pthread_t thread);
thread
:要终止的线程ID。
返回值:成功返回0,失败返回错误码。
示例代码:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <string.h> void *thread_fun(void *argc) { //回调函数,子线程执行的函数 while (1) { printf("new tread "); sleep(1); } return NULL; } int main(int argc,char*argv[]){ int ret; pthread_t tid; ret = pthread_create(&tid, NULL, thread_fun, NULL); //创建子线程 if (ret != 0) { printf("create failed "); exit(1); } sleep(2); //等待一段时间后取消线程 pthread_cancel(tid); //请求取消线程 pthread_join(tid, NULL); //等待线程结束并释放资源 printf("main thread "); return 0; }
运行结果:
new tread new tread main thread
四、常见问题解答栏目
Q1: 什么时候使用线程分离?
A1: 当不需要主线程等待子线程完成,并且不关心子线程的返回值时,可以使用线程分离,这样可以避免资源泄漏,同时提高程序的效率。
Q2: 如何避免线程泄漏?
A2: 确保每个创建的线程都被正确地连接或分离,对于不需要等待的线程,使用pthread_detach()
将其设置为分离状态;对于需要等待的线程,使用pthread_join()
等待其结束。
到此,以上就是小编对于“分离线程 编程linux”的问题就介绍到这了,希望介绍的几点解答对大家有用,有任何问题和不懂的,欢迎各位朋友在评论区讨论,给我留言。
原创文章,作者:K-seo,如若转载,请注明出处:https://www.kdun.cn/ask/678275.html