线程等待

为什么需要线程等待?

1.线程的入口函数是有返回值的,有时候需要查看这个结果;
2.这个结果会在线程退出时一直在内存中保存着,直到有其他线程来读取,才会释放;
3.否则,会产生类似于僵尸进程的场景,创建新的线程不会复用刚才退出线程的地址空间。
4.如果没有pthread_join(),主线程会很快结束从而使整个进程结束,从而使创建的线程没有机会开始执行就结束了,加入pthread_join()后,主线程会一直等待,直到等待的线程结束自己,才会结束这个整个进程,也就是说pthread_join可以使创建的线程有机会执行

pthread_join

功能:等待线程结束(此函数使一个线程等待另一个线程结束)
原型:
int pthread_join(pthread_t thread,void**value_ptr)
参数说明:
thread:线程ID
value_ptr:它指向一个指针,后者指向线程的返回值

ps:参数value_ptr 是输出型参数,需要输出的内容是void*,所以在这里
   是void**来接收参数

调用该函数的线程将会挂起等待,直到ID为thread的线程终止
此等待是阻塞式等待,就是会等待的线程什么也不做,一直等待某线程结束,才会去做自己该做的事

thread线程以不同的方法终止,那通过pthread_join得到的终止状态是不同的,如下:

1.如果ID为thread的线程通过return返回,value_ptr
  所指向的单元里存放的是thread线程函数的返回值

2.如果ID为thread的线程是被别的线程调用pthread_cancel
  异常终止,value_ptr所指向的单元里存放的是常数PTHREAD_CANCELED

3.如果ID为thread的线程是自己调用pthread_exit终止的,value_ptr
  所指向的单元里存放的是传给pthread_exit的参数

4.如果对ID为thread的线程的终止状态不感兴趣,可以传NULL给value_ptr参数

示例

1.
代码

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
typedef struct Student
{
    int id;
    int score;
    char *name;
}Student;
void*ThreadEntry(void*arg)
{
    (void)arg;
    int count=0;
    Student*p=(Student*)malloc(sizeof(Student));
    p->id=29;
    p->score=100;
    p->name="xiaoming";
    while(1)
    {
        ++count;
        if(count>=5)
            return (void*)p;
        printf("I am thread\n");
        sleep(1);
    }
}

int main()
{
    pthread_t tid;
    void*ret;
    int thread=0;
    thread=pthread_create(&tid,NULL,ThreadEntry,NULL);
    if(thread!=0)
    {
        perror("pthread_create");
        exit(1);
    }
    printf("I am main\n");
    pthread_join(tid,&ret);
    Student*st=(Student*)ret;
    printf("id=%d,score= %d ,name=%s\n",st->id,st->score,st->name);
    return 0;
}

运行结果:
这里写图片描述

2.
代码:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
void*ThreadEntry(void*arg)
{
    int count=0;
    int*p=(int*)malloc(sizeof(int));
    *p=50;
    while(1)
    {
        ++count;
        if(count>5)
            pthread_exit(p);
        printf("I am thread\n");
        sleep(1);
    }
}
int main()
{
    pthread_t tid;
    void*ret;
    int thread;
    thread=pthread_create(&tid,NULL,ThreadEntry,NULL);
    if(thread!=0)
    {
        perror("pthread_create");
        exit(1);
    }
    printf("I am main\n");
    pthread_join(tid,&ret);
    printf("ret=%d\n",*(int*)ret);
    return 0;
}

运行结果:
这里写图片描述

ps:void*是怎么构造的,那就一定要按相同的类型去解析

3.
代码:

#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<stdlib.h>
void*thread1(void*arg)
{
    printf("thread1 is  return..............\n");
    int*p=(int*)malloc(sizeof(int));
    *p=20;
    return (void*)p;
}
void*thread2(void*arg)
{
    printf("thread2  is  pthread_exit!\n");
    int*p=(int*)malloc(sizeof(int));
    *p=50;
    pthread_exit(p);
}
void*thread3(void*arg)
{
    while(1)
    {
        printf("thread3 is pthread_cancel.............\n"); 
        sleep(1);
    }
}
int main()
{
    pthread_t tid;
    void*ret;
    //thread1
    pthread_create(&tid,NULL,thread1,NULL);
    pthread_join(tid,&ret);
    printf("thread1 return,thread is %1x,return code:%d\n",tid,*(int*)ret);
    free(ret);//malloc开辟内存后记得释放开辟的空间
    sleep(1);
    printf("\n");
    //thread2 
    pthread_create(&tid,NULL,thread2,NULL);
    pthread_join(tid,&ret);
    printf("thread2 pthread_exit,thread is %1x,return code:%d\n",tid,*(int*)ret);
    free(ret);//malloc开辟内存后记得释放开辟的空间
    sleep(1);
    printf("\n");
    //thread3 
    pthread_create(&tid,NULL,thread3,NULL);
    sleep(3);
    pthread_cancel(tid);
    pthread_join(tid,&ret);
    if(ret==PTHREAD_CANCELED)
        printf("thread3 pthread_cancel,thread is %1x,return code:PTHREAD_CANCELED\n",tid);
    return 0;
}

运行结果:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值