Linux pthread_join的使用注意


pthread_join

在Linux中,新建的线程并不是在原先的进程中,而是系统通过一个系统调用clone()。该系统copy了一个和原先进程完全一样的进程,并在这个进程中执行线程函数。不过这个copy过程和fork不一样。 copy后的进程和原先的进程共享了所有的变量,运行环境。这样,原先进程中的变量变动在copy后的进程中便能体现出来。


回收时子线程资源避免回收局部变量

正确回收方法一

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


struct test_st
{
    int val;
    char str[10];
};
void *tid_cb(void *arg)
{
    struct test_st *tval;
    tval = malloc(sizeof(tval));
    tval->val = 100;
    strcpy(tval->str, "hello world");
    return (void *)tval;
}
int main()
{
    pthread_t tid;
    int ret = pthread_create(&tid, NULL, tid_cb, NULL);
    if (ret != 0)
    {
        fprintf(stderr, "pthread_create: %s\n", strerror(ret));
    }
    struct test_st *retval;
    ret = pthread_join(tid, (void **)&retval);
    if (ret != 0)
    {
        fprintf(stderr, "pthread_join: %s\n", strerror(ret));
    }
    printf("child thread exit with val=%d,str=%s\n", retval->val, retval->str);
    pthread_exit(NULL);
    return 0;
}

正确回收方法二

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

struct test_st
{
    int val;
    char str[10];
};
void *tid_cb(void *arg)
{
    struct test_st *tval = (struct test_st *)arg;
    tval = malloc(sizeof(tval));
    tval->val = 100;
    strcpy(tval->str, "hello world");
    return (void *)tval;
}

int main()
{
    pthread_t tid;
    struct test_st *retval;
    struct test_st arg;
    int ret = pthread_create(&tid, NULL, tid_cb, (void *)&arg);
    if (ret != 0)
    {
        fprintf(stderr, "pthread_create: %s\n", strerror(ret));
    }
    ret = pthread_join(tid, (void **)&retval);
    if (ret != 0)
    {
        fprintf(stderr, "pthread_join: %s\n", strerror(ret));
    }
    printf("child thread exit with val=%d,str=%s\n", retval->val, retval->str);
    pthread_exit(NULL);
    return 0;
}

输出:child thread exit with val=100,str=hello world


错误写法:子线程中的局部变量作为回收值,此时会出现段错误

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

struct test_st
{
    int val;
    char str[10];
};
void *tid_cb(void *arg)
{
    struct test_st *tval;
    tval = malloc(sizeof(tval));
    tval->val = 100;
    strcpy(tval->str, "hello world");
    return (void *)tval;
}
void *tid_cb1(void *arg){
    int pval=100;
    return (void*)pval;
}
int main()
{
    pthread_t tid;
    int ret = pthread_create(&tid, NULL, tid_cb1, NULL);
    //struct test_st *retval;
    int *retval;
    pthread_join(tid, (void **)&retval);
    //printf("child thread exit with val=%d,str=%s\n", retval->val, retval->str);
    printf("child thread exit with val=%d ",*retval);
    pthread_exit(NULL);
    return 0;
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: pthread_join是一个函数,用于等待指定的线程结束并回收其资源。在调用pthread_join之前,必须先创建一个线程,并且该线程必须是可连接的。该函数的原型如下: int pthread_join(pthread_t thread, void **retval); 其中,thread参数是要等待的线程的标识符,retval参数是指向线程返回值的指针。如果线程没有返回值,则可以将该参数设置为NULL。该函数返回表示成功,否则返回错误代码。 ### 回答2: pthread_join()是Linux中用于等待一个线程结束的函数。当我们创建了一个线程,就会在主线程中调用pthread_create()来启动该线程。但是,在主线程中,我们通常希望Wait线程执行完毕后才能继续处理其他任务。此时,就需要使用pthread_join()函数来等待线程的结束。 pthread_join()函数的用法如下: int pthread_join(pthread_t thread, void **retval); 其中,thread表示要等待的线程句柄;retval为返回值参数,是一个指向线程的返回值指针的指针。如果线程在结束时未返回任何值,则可以将该参数设置为NULL。 具体地,pthread_join()的作用是,当调用该函数时,主线程会进入等待状态,并阻塞到该函数的调用处。只有当thread线程退出时,主线程才会从pthread_join()函数中返回,并根据线程的返回值更新retval所指向的数据。 需要注意的是,一旦调用了pthread_join()函数,被等待的线程将会被回收,而不能再被其他线程所使用。因此,我们需要在线程的使用完毕后再调用pthread_join()函数来等待线程的结束。 总之,pthread_join()函数是用于等待Linux线程结束的关键函数之一,可以防止并发操作时出现混乱,保证线程的顺序执行和正确性。 ### 回答3: pthread_join是一个用于等待线程结束并回收资源的函数。在使用线程时,有时需要等待一个或多个线程完成后再继续执行,则可以使用pthread_join。 在使用pthread_join函数时,需要注意以下几个方面: 1. pthread_join函数的第一个参数是指向线程ID的指针,第二个参数为指向线程返回值的指针。当线程执行完毕时,其返回值就会被写入到指定的返回值指针指向的内存空间中。 2. 调用pthread_join函数会阻塞当前线程,直到指定的线程结束并回收了其资源后才会返回。如果不等待线程结束,主线程可能会在未完成的线程仍在运行时退出,从而导致未完成的线程出现问题。 3. 如果线程已经被pthread_detach分离了,pthread_join将会返回一个错误。所以,在调用pthread_join之前,需要确保该线程没有被分离。 在使用pthread_join时,可以指定连接模式 PTHREAD_CREATE_JOINABLE 或 PTHREAD_CREATE_DETACHED。默认情况下,创建的线程是 PTHREAD_CREATE_JOINABLE 模式,即可以被其他线程连接;如果需要将线程设为 PTHREAD_CREATE_DETACHED 模式,则需要调用pthread_detach函数。 在使用多线程时,pthread_join非常重要,它能够确保每个线程都已经完成工作,精确控制多线程程序的执行顺序,避免不同线程之间的竞争和死锁等问题的发生。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VioletEvergarden丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值