Linux---线程相关函数

1. 线程相关函数

线程终止

  1. 从线程函数return。这种方法对主线程不适用,从main函数return相当于调用exit。
  2. 线程可以调用pthread_ exit终止自己
  3. 一个线程可以调用pthread_ cancel终止同一进程中的另一个线程

1.1 pthread_exit函数

exit()是终止进程,并不是终止线程,接收不到线程的退出码。

void *thread_run(void* arg)
{
  printf("%s,%lu,pid : %d\n",(char*)arg,pthread_self(),getpid());
  sleep(10);
  exit(20); 
  return (void*)10;
}

int main()
{
  pthread_t tid;
  pthread_create(&tid,NULL,thread_run,"thread 1");


  printf("main : %lu,pid : %d\n",pthread_self(),getpid());
  void* ret = NULL;
  pthread_join(tid,&ret);
  printf("thread quit code :%d\n",(long long)ret);
  return 0;
}

在这里插入图片描述

功能:线程终止
原型 void pthread_exit(void *value_ptr);
参数value_ptr:value_ptr不要指向一个局部变量。
返回值:无返回值,跟进程一样,线程结束的时候无法返回到它的调用者(自身)

void *thread_run(void* arg)
{
  printf("%s,%lu,pid : %d\n",(char*)arg,pthread_self(),getpid());
  sleep(5);
  pthread_exit((void*)10);
}

int main()
{
  pthread_t tid;
  pthread_create(&tid,NULL,thread_run,"thread 1");


  printf("main : %lu,pid : %d\n",pthread_self(),getpid());
  void* ret = NULL;
  pthread_join(tid,&ret);
  printf("thread quit code :%d\n",(long long)ret);
  return 0;
}

在这里插入图片描述

1.2 pthread_join函数

功能:等待线程结束
原型 int pthread_join(pthread_t thread, void **value_ptr);
参数thread:线程ID value_ptr:它指向一个指针,后者指向线程的返回值
返回值:成功返回0;失败返回错误码

为什么需要线程等待?

  1. 已经退出的线程,其空间没有被释放,仍然在进程的地址空间内。
  2. 创建新的线程不会复用刚才退出线程的地址空间。
  3. 主线程需要知道所创建的新线程是否有完成任务。并且可以避免像僵尸进程的问题

对于pthread_join函数来说,我们只认为它等成功了,因为一旦线程出现了错误,进程就直接被杀死了(信号发送的单位是进程),进程是线程的载体。

#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
void *thread_run(void* arg)
{
  printf("%s,%lu,pid : %d\n",(char*)arg,pthread_self(),getpid());
  sleep(10);
  return (void*)10;
}

int main()
{
  pthread_t tid;
  pthread_create(&tid,NULL,thread_run,"thread 1");


  printf("main : %lu,pid : %d\n",pthread_self(),getpid());
  void* ret = NULL;
  pthread_join(tid,&ret);
  printf("thread quit code :%d\n",(long long)ret);
  return 0;
}

在这里插入图片描述
此时所创建的线程发现了除0的错误,此时等待十秒之后,进程就会直接被杀死,我们根本接收不到这个线程的退出码。

void *thread_run(void* arg)
{
  printf("%s,%lu,pid : %d\n",(char*)arg,pthread_self(),getpid());
  sleep(10);
  int a;
  a /= 0;
  return (void*)10;
}

在这里插入图片描述

1.3 pthread_cancel函数

功能:取消一个执行中的线程
原型 int pthread_cancel(pthread_t thread);
参数thread:线程ID
返回值:成功返回0;失败返回错误码

#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>
void *thread_run(void* arg)
{
  while(1){
    printf("%s,%lu,pid : %d\n",(char*)arg,pthread_self(),getpid());
    sleep(1);
  }
}

int main()
{
  pthread_t tid;
  pthread_create(&tid,NULL,thread_run,"thread 1");


  printf("main : %lu,pid : %d\n",pthread_self(),getpid());
  sleep(10);

  pthread_cancel(tid);
  printf("new thread %lu be canceled\n",tid);
  
  
  void* ret = NULL;
  pthread_join(tid,&ret);
  printf("thread quit code :%d\n",(long long)ret);//对于云服务器是x64平台,所以需要8位
  return 0;
}

在这里插入图片描述
调用该函数的线程将挂起等待,直到id为thread的线程终止。thread线程以不同的方法终止,通过pthread_join得到的终止状态是不同的,总结如下:

  1. 如果thread线程通过return返回,value_ ptr所指向的单元里存放的是thread线程函数的返回值。
  2. 如果thread线程被别的线程调用pthread_ cancel异常终掉,value_ ptr所指向的单元里存放的是常数PTHREAD_ CANCELED(这是一个宏定义,本质就是-1)。
  3. 如果thread线程是自己调用pthread_exit终止的,value_ptr所指向的单元存放的是传给pthread_exit的参数。
  4. 如果对thread线程的终止状态不感兴趣,可以传NULL给value_ ptr参数

1.4 pthread_detach

分离线程

  1. 默认情况下,新创建的线程是joinable的,线程退出后,需要对其进行pthread_join操作,否则无法释放资源,从而造成系统泄漏
  2. 如果不关心线程的返回值,join是一种负担,这个时候,我们可以告诉系统,当线程退出时,自动释放线程资源。

int pthread_detach(pthread_t thread);

可以是线程组内其他线程对目标线程进行分离,也可以是线程自己分离:

pthread_detach(pthread_self());

线程分离以后,主线程以后就再也不需要关心这个线程了,在这个线程结束以后,会自动的进行资源释放。但是这里有一点:如果这个分离的线程出现了问题,依旧会导致进程的退出

#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<stdlib.h>
void *thread_run(void* arg)
{
  //线程自己对自己进行了分离
  pthread_detach(pthread_self());
  while(1){
    printf("%s,%lu,pid : %d\n",(char*)arg,pthread_self(),getpid());
    sleep(1);
    break;
  }
  //出现了除0的错误
  int a = 10;
  a /= 0;
  return (void*)10;
}

int main()
{
  pthread_t tid;
  pthread_create(&tid,NULL,thread_run,"thread 1");


  printf("main : %lu,pid : %d\n",pthread_self(),getpid());
  sleep(3);

  
  
  void* ret = NULL;
  printf("thread quit code :%d\n",(long long)ret);//对于云服务器是x64平台,所以需要8位
  return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值