1.线程的概念 一个正在运行的函数 posix线程是一套标准,而不是实现 线程标识:pthread_t pthread_equal(); pthread_self();
2.线程的创建 pthread_create(pthread_t *thread,const pthread_attr_t attr, void(*start_routine)(void *),void *arg);
线程的调度取决于调度器策略
线程的终止 3种方式:1)线程从启动返回 2)线程可以被同一个进程另一个线程取消 3)pthread_exit(NULL)
栈的清理 pthread_cleanup_push() // pthread_cleanup_pop() // 注意,这2个是宏,需要成对出现,否则编译错误
线程的取消选项 pthread_cancel() 线程的分离 pthread_detach()
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
// 清理函数:用于释放资源
void cleanup_handler(void *arg) {
char *message = (char *)arg;
printf("Cleaning up: %s\n", message);
free(message); // 释放动态分配的内存
}
// 线程函数
void *thread_func(void *arg) {
// 1. 申请资源(模拟)
char *message = malloc(1024);
sprintf(message, "Memory allocated at address %p", message);
// 2. 将清理函数压栈,并将资源地址作为参数传入
pthread_cleanup_push(cleanup_handler, message);
// 3. 这里是线程的主要工作区域
// 模拟一些工作,在此期间线程可能被取消
for (int i = 0; i < 5; i++) {
printf("Working... %d\n", i);
sleep(1);
// 如果线程在这段循环中被取消,cleanup_handler 会被自动调用
}
// 4. 正常流程:弹出清理函数但不执行(因为参数为0)
// 因为我们正常完成了工作,所以要自己释放内存,而不是靠清理handler
printf("Work done normally, popping without execute.\n");
pthread_cleanup_pop(0); // 参数 0 表示不执行清理函数
// 5. 自己手动释放资源(正常流程)
free(message);
return NULL;
}
int main() {
pthread_t tid;
void *retval;
pthread_create(&tid, NULL, thread_func, NULL);
// 主线程等待一会儿,然后取消新线程
sleep(2);
printf("Main: Canceling the thread...\n");
pthread_cancel(tid);
// 等待线程结束
pthread_join(tid, &retval);
if (retval == PTHREAD_CANCELED) {
printf("Main: Thread was canceled.\n");
} else {
printf("Main: Thread exited normally.\n");
}
return 0;
}
/*主线程在 2 秒后取消子线程。子线程在 `for` 循环中被取消,这会触发清理机制,自动调用 `cleanup_handler` 来释放 `message` 指向的内存。因此你不会看到 "Work done normally..." 的消息,但会看到 "Cleaning up..." 的消息。*/
能创建多少个线程? 取决栈大小 ,ulimit -a 64位: stack size (kbytes, -s) 8192
32位: 1G:内核态 3G:用户态(<3G)
3.线程同步 互斥量: pthread_mutex_t; pthread_mutex_init(); pthread_mutex_destroy(pthread_mutex_t* mutex); pthread_mutex_lock(); pthread_mutex_trylock(); pthread_mutex_unlock();
条件变量: pthread_cond_t; pthread_cond_init(); pthread_cond_destroy(); pthread_cond_wait() pthread_cond_broadcast(); pthread_cond_singl();
信号量:
4.线程属性 线程同步的属性
5.重入 线程与信号 线程与fork