pthread_join、pthread_detach、pthread_cancel、pthread_attr_、线程同步互斥

发布时间 2023-05-04 11:04:30作者: WTSRUVF

# pthread_join

/*

        #include <pthread.h>

        int pthread_join(pthread_t thread, void **retval);
            功能:和一个已经终止的线程进行连接
                    回收线程的资源
                    阻塞函数,调用一次只能回收一个线程
                    任何线程都可以wait其它线程一般在主线程中使用
            参数:
                thread:需要回收的线程ID
                retval:输出参数,接受子线程的返回值
            返回值:
                成功:0
                失败:非0,返回的错误号
*/

#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

int retval = 10;
void *callback(void *arg)
{
    printf("I am a child thread\n");
    //return NULL;
    // int retval = 10; // 返回局部变量地址??? 那肯定不行,需要返回全局变量的地址
    pthread_exit((void*)&retval);
}


int main()
{
    pthread_t thread;
    int ret = pthread_create(&thread, NULL, callback, NULL);

    if(ret != 0)
    {
        printf("pthread_create error: %s\n", strerror(ret));
        exit(-1);
    }

    for(int i = 0; i < 5; i++)
    {
        printf("%d\n", i);
    }

    sleep(1);

    int *thread_retval;
    // 回收子线程
    ret = pthread_join(thread, NULL);

    ret = pthread_join(thread, (void*)&thread_retval);
    if(ret != 0)
    {
        printf("pthread_create error: %s\n", strerror(ret));
        exit(-1);
    }
    printf("child thread recover success: %d\n", *thread_retval);

    pthread_exit(NULL);








    return 0;
}

 

 

 

# pthread_detach

 

/*
        #include <pthread.h>

        int pthread_detach(pthread_t thread);
            功能:对一个线程标记为detach
                如果一个线程被标记为detach,则线程退出时会自动释放资源,不需要pthread_join
                1、不能多次分离
                2、不能join已经detach的线程
            参数:
                thread:需要分离的xianchengID
            返回值:
                成功:0
                失败:错误号



*/
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

int retval = 10;
void *callback(void *arg)
{
    printf("I am a child thread\n");
    //return NULL;
    // int retval = 10; // 返回局部变量地址??? 那肯定不行,需要返回全局变量的地址
    pthread_exit((void*)&retval);
}


int main()
{
    pthread_t thread;
    int ret = pthread_create(&thread, NULL, callback, NULL);
    

    if(ret != 0)
    {
        printf("pthread_create error: %s\n", strerror(ret));
        exit(-1);
    }

    for(int i = 0; i < 5; i++)
    {
        printf("%d\n", i);
    }

    sleep(1);

    int *thread_retval;
    // 回收子线程
    // ret = pthread_join(thread, NULL);

    // ret = pthread_join(thread, (void*)&thread_retval);
    ret = pthread_detach(thread);
    if(ret != 0)
    {
        printf("pthread_create error: %s\n", strerror(ret));
        exit(-1);
    }
    printf("child thread recover success: %d\n", *thread_retval);

    pthread_exit(NULL);








    return 0;
}

 

 

 

 

# pthread_cancel

 

/*
        #include <pthread.h>

        int pthread_cancel(pthread_t thread);    
            功能:取消线程(让线程终止)
                不是立即终止,而是当子线程执行到一个取消点
                取消点:系统规定好的一些系统调用
        



*/

#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

int retval = 10;
void *callback(void *arg)
{
    printf("I am a child thread\n");
    //return NULL;
    // int retval = 10; // 返回局部变量地址??? 那肯定不行,需要返回全局变量的地址

    for(int i = 0; i < 5; i++)
    {
        printf("child: %d\n", i);
    }



    // pthread_exit((void*)&retval);
    return NULL;
}


int main()
{
    pthread_t thread;
    int ret = pthread_create(&thread, NULL, callback, NULL);
    

    if(ret != 0)
    {
        printf("pthread_create error: %s\n", strerror(ret));
        exit(-1);
    }

    pthread_cancel(thread);


    for(int i = 0; i < 5; i++)
    {
        printf("%d\n", i);
    }




    pthread_exit(NULL);








    return 0;
}

 

 

 

 

# pthread_attr_

 

/*
        #include <pthread.h>

        // 初始化线程属性变量
        int pthread_attr_init(pthread_attr_t *attr);
        // 释放线程属性变量
        int pthread_attr_destroy(pthread_attr_t *attr);

        // 设置线程分离状态
        int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
        // 获取线程分离状态
        int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);

        // 其余功能 可以用 man pthread_attr_    进行查看

*/

#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>

int retval = 10;
void *callback(void *arg)
{
    printf("I am a child thread\n");
    //return NULL;
    // int retval = 10; // 返回局部变量地址??? 那肯定不行,需要返回全局变量的地址
    pthread_exit((void*)&retval);
}


int main()
{

    pthread_attr_t attr;
    // 初始化线程属性资源
    pthread_attr_init(&attr);
    // 通过属性设置分离
    pthread_attr_setdetachsate(&attr, PTHREAD_CREATE_DETACHED); // == pthread_detach(thread);

    pthread_t thread;
    int ret = pthread_create(&thread, &attr, callback, NULL);
    

    if(ret != 0)
    {
        printf("pthread_create error: %s\n", strerror(ret));
        exit(-1);
    }

    for(int i = 0; i < 5; i++)
    {
        printf("%d\n", i);
    }

    sleep(1);

    int *thread_retval;
    // 回收子线程
    // ret = pthread_join(thread, NULL);

    // ret = pthread_join(thread, (void*)&thread_retval);
    // ret = pthread_detach(thread);
    // if(ret != 0)
    // {
    //     printf("pthread_create error: %s\n", strerror(ret));
    //     exit(-1);
    // }
    printf("child thread recover success: %d\n", *thread_retval);

    // 释放线程属性资源
    pthread_attr_destroy(&attr);

    pthread_exit(NULL);










    return 0;
}

 

 

 

 

# 线程同步互斥

 

/*

    需求:三个售票窗口卖100张票
    由于票是互斥变量,需要实现同步互斥
    本代码使用了皮特森算法进行限制
*/

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>


int j, turn;
int flag[3] = {0, 0, 0};

void *callback(void* arg)
{
    int id = *(int *)arg;
    while(j < 100)
    {
        flag[id] = 1; 
        if(turn == id) turn = (turn + (rand() % 2) + 1) % 3; // rand保证窗口买票的随机性
        while((flag[(id + 1) % 3] || flag[(id + 2) % 3]) && turn != id && j < 100); // 判断100,防止死循环
        if(j >= 100) break;
        sleep(1);
        printf("%d sell the %d'th ticket\n", id, ++j);
        flag[id] = 0;
    }
    
    return NULL;
}


int main()
{
    j = 0;
    turn = 0;

    pthread_t thread[3];
    int id0 = 0, id1 = 1, id2 = 2;
    pthread_create(&thread[0], NULL, callback, (void *)&id0);
    pthread_create(&thread[1], NULL, callback, (void *)&id1);
    pthread_create(&thread[2], NULL, callback, (void *)&id2);

    // pthread_detach(thread[0]);
    // pthread_detach(thread[1]);
    // pthread_detach(thread[2]);
    pthread_join(thread[0], NULL); // pthread_join是阻塞函数
    pthread_join(thread[1], NULL);
    pthread_join(thread[2], NULL);

    printf("tickets sell out!!!\n");

    pthread_exit(NULL);


    // sleep(60);



    return 0;
}