线程

28 阅读2分钟

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