1.开发背景
Linux 线程区分于FreeRTOS,线程的属性形态有2中,在 pthread.h 中有注解,如下。
/* Detach state. */
enum
{
PTHREAD_CREATE_JOINABLE,
#define PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_JOINABLE
PTHREAD_CREATE_DETACHED
#define PTHREAD_CREATE_DETACHED PTHREAD_CREATE_DETACHED
};
线程的的创建可以分为 joinable 和 detached 共 2 种状态,其中 detached 属于分离状态,线程的创建模式是可结合状态,即 joinable,这种情况下线程结束后需要调用 pthread_join 回收资源,否则有出现内存溢出,同时 pthread_join 也起到了等待线程执行完成的功能。
至于 detached 状态指的是线程分离,即不需要特意调用线程回收功能,线程结束后自动回收。
2.开发需求
设计实验:
1)循环创建线程为可结合状态,不调用 pthread_join,观察内存的变化;
3.开发环境
ubuntu20.04 + RK3568 + Linux4.19.232
4.实现步骤
4.1 实现代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include "com_save.h"
#include "app_log.h"
#define FILE_PATH_TEST ("/home/reetoo/log/test")
typedef struct
{
/* 线程 */
pthread_t thread_join;
pthread_t thread_detach;
}ctrl_t;
static ctrl_t s_ctrl = {0};
static ctrl_t *p = &s_ctrl;
/* 线程函数 */
void* pthread_process(void* arg)
{
for (int i = 0; i < 1000 * 10000; i++);
alog_info("%s thread, pid: %d, pthread_self: %ld\r\n", __func__, getpid(), pthread_self());
return NULL;
}
/* 主函数 */
int main(int argc, char* argv[])
{
/* 文件保存初始化 */
csave_init(FILE_PATH_TEST);
/* 日志模块初始化 */
alog_init();
/* 打印日志 */
alog_info("i am main, pid: %d, pthread_self: %ld\r\n", getpid(), pthread_self());
/* 设置线程属性 */
pthread_attr_t attr;
pthread_attr_init(&attr);
/* 创建可join线程 */
static char join_arg[] = "join";
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); // 设置分离属性
pthread_attr_setstacksize(&attr, 1024 * 1024); // 设置栈大小
for (int i = 0; i < 100; i++)
{
alog_info("create new thread, i: %d\r\n", i);
pthread_create(&p->thread_join, &attr, (void*)pthread_process, join_arg);
// pthread_join(p->thread_join, NULL);
sleep(1);
}
/* 销毁线程属性 */
pthread_attr_destroy(&attr);
return 0;
}
4.2 测试结果
使用 top 查看内存变化如下,一直递增,由于 top 并非事实刷新,只能看到内存的变化趋势。因此如果不需要同步操作,可以直接设置线程为分离模式,防止内存溢出。