线程控制(二)------线程等待、分离与结合属性

线程等待

为什么需要线程的等待?

  • 已经退出的线程,其空间没有被释放,仍然在进程的地址空间。
  • 创建新的线程不会复用刚才退出线程的地址空间。
    这里写图片描述
    调用该函数的线程将挂起状态,直到id为thread的线程终止,thread线程以不同的方法终止,通过pthread_join得到的终止状态是不同的,总结如下:

1、 如果thread线程通过return返回,value_ptr所指向的单元里存放的是thread线程函数的返回值。
2、如果thread线程被别的线程调用pthread_cancel异常终掉,value_ptr所指向的单元里存放的是常数PTHREAD_CANCELED(为-1是void*类型的)。
3、如果thread线程是自己调用pthreadexit终止的,valueptr所指向的单元存放的是传给ptrread_exit的参数。
4、如果对thread线程的终止状态不感兴趣,可以传给NULL给value_ptr参数。

这里写图片描述
我们来看一个线程等待的例子:

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

void *thread1(void *arg)
{
    printf("thread 1 returning ...\n");
    int *p=(int*)malloc(sizeof(int));
    *p=1;
    return (void*)p;
}

void *thread2(void *arg)
{
    printf("thread 2 exiting  ...\n");
    int *p=(int*)malloc(sizeof(int));
    *p=2;
    pthread_exit((void*)p);
}

void *thread3(void *arg)
{
    while(1){
    printf("thread 3 is running ...\n");
    sleep(1);
    }
    return NULL;
}

int main()
{
    pthread_t  tid;
    void *ret;

     //thread 1  return
     pthread_create(&tid,NULL,thread1,NULL);
     pthread_join(tid,&ret);
     printf("thread return,thread id %x,return code:%d\n",tid,*(int*)ret);
     free(ret);


      //thread 2 exit
      pthread_create(&tid,NULL,thread2,NULL);
      pthread_join(tid,&ret);
      printf("thread return ,thread id %x,return code:%d\n",tid,*(int*)ret);
      free(ret);

      //thread 3 cancel by other
      pthread_create(&tid,NULL,thread3,NULL);
      sleep(3);
      pthread_cancel(tid);
      pthread_join(tid,&ret);
      if(ret==PTHREAD_CANCELED)
      {
     printf("thread return,thread id %x,return code:PTHREAD_CANCELED\n",tid);
      }
     else
     printf("thread return,thread id %x,return code:NULL\n",tid);
}

运行结果如下所示:

这里写图片描述

分离线程

默认情况线程是可结合的,代表的含义就是这个线程必须被等待。
- 默认情况下新创建的线程是joinable的,线程退出后,需要对其进行pthread_join操作,否则无法释放资源,从而造成系统柜的内存泄漏的问题。
- 如果不关心线程的返回值,join是一种负担,这个时候,我们可以告诉系统,当线程退出时,自动释放线程资源。
这里写图片描述
这个函数的作用是可以是线程组内其他线程对目标线程进行分离,也可以是线程自己进行分离。
这里写图片描述
joinable和分离是冲突的,一个线程不可能既是joinable也是分离的。
线程的分离状态决定了一个线程以什么样的方式来终止自己。在默认的情况下线程是非分离状态的,这种情况下,原有的线程等待创建的线程结束。只有当 pthread_join ()函数返回时,创建的线程才算终止,才能释放自己占有用的系统资源,而分离线程不是这样子的,它没有被其他的线程所等待,自己运行结束了,线程也就终止了,马上释放系统资源。程序员应该根据自己的需要,选择适当的分离状态,所以如果我们在创建线程时就知道不需要了解线程的终止状态,则可以 pthread_attr_t结构中,的detachstate线程属性,让线程以分离状态启动。
示例代码:

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


void *thread_run(void *arg)
{
    pthread_detach(pthread_self());
    printf("%s\n",(char*)arg);
    return NULL;
}


int main()
{
    pthread_t tid;
    if(pthread_create(&tid,NULL,thread_run,"thread1 run ...")!=0){
    printf("create thread error\n");
    return 1;
    }
    int ret=0;
    sleep(1);
    if(pthread_join(tid,NULL)==0){
    printf("pthread wait success\n");
    ret=0;
    }
    else{
    printf("pthread wait failed\n");
    ret=1;
    }
return ret;
}

结果如下:在子线程运行完毕后,分离tid后,查看是否能够等待成功,若不能则说明分离成功。
这里写图片描述

猜你喜欢

转载自blog.csdn.net/daboluo521/article/details/80140424