Linux多线程学习------02

1.创建线程

  • 功能: 创建一个新的线程
  • 原型
    int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void * (start_routine)(void), void *arg);
  • 参数
    thread:返回线程ID
    attr:设置线程的属性,attr为NULL表示使用默认属性
    start_routine:是个函数地址,线程启动后要执行的函数
    arg:传给线程启动函数的参数
    返回值:成功返回0;失败返回错误码
  • pthread_ create函数第一个参数指向一个虚拟内存单元,该内存单元的地址即为新创建线程的线程ID,属于NPTL线程库的范畴。线程库的后续操作,就是根据该线程ID来操作线程的。
  • 线程库NPTL提供了pthread_ self函数,可以获得线程自身的ID:
//---------------------------------------------------
//不是系统调用------------是库函数
//库函数 =》posix 线程库 pthread 中的 p就表示 posix
//1.创建线程
//2.终止线程
//3.等待线程
//4.线程分离

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

typedef void*(*p)(void*);

void* ThreadEntry(void* arg){
  (void)arg;
  while(1){
    printf("In ThreadEntry, %lu\n",pthread_self());
    sleep(1);
  }
}
int main()
{
  pthread_t tid;
  pthread_create(&tid, NULL, ThreadEntry, NULL);

  while(1){
    printf("In main Thread, %lu\n", pthread_self());
    sleep(1);
  }

  return 0;
}

2.线程终止

  • void pthread_exit(void *value_ptr); //ptr必须是全局变量或者malloc分配的,否则线程结束该空间也被释放。
  • int pthread_cancel(pthread_t thread);
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>

int arr[100000000] = {0};
void* ThreadEntry(void* arg)
{
  (void)arg;
  size_t i = 0;
  for(; i<sizeof(arr)/sizeof(arr[0]); ++i)
  {
  		arr[i] = i;
  }
  pthread_exit(0);//很少用到
  return NULL;
}

int main()
{
  pthread_t tid;
  pthread_create(&tid,NULL,ThreadEntry, NULL);

  printf("In MainThread\n");
  //pthread_cancel(tid);//尽量少用,线程之间抢占式调度,可能线程还没执行完任务就被中断了
  size_t i = 0;
  for(; i<sizeof(arr)/sizeof(arr[0]); ++i)
  {
    printf("%d\n",arr[i]);
    sleep(1);
  }
  return 0;
}

3.线程等待

为什么需要线程等待?
避免出现类似僵尸进程,造成内存泄漏
功能: 等待线程结束
原型
int pthread_join(pthread_t thread, void **value_ptr);
参数
thread: 线程ID
value_ptr: 它指向一个指针,后者指向线程的返回值
返回值: 成功返回0;失败返回错误码

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

  1. 如果thread线程通过return返回,value_ ptr所指向的单元里存放的是thread线程函数的返回值。
  2. 如果thread线程被别的线程调用pthread_ cancel异常终掉,value_ ptr所指向的单元里存放的是常数
    PTHREAD_ CANCELED。
  3. 如果thread线程是自己调用pthread_exit终止的,value_ptr所指向的单元存放的是传给pthread_exit的参 数。
  4. 如果对thread线程的终止状态不感兴趣,可以传NULL给value_ ptr参数。
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>

int arr[100000000] = {0};
void* ThreadEntry(void* arg)
{
  (void)arg;
  size_t i = 0;
  for(; i<sizeof(arr)/sizeof(arr[0]); ++i)
  {
   arr[i] = i;
  }
  return NULL;
}
//线程等待 pthread_join 回收线程 显式 其实是为了等待对应线程结束后在执行代码
int main()
{
  pthread_t tid;
  pthread_create(&tid,NULL,ThreadEntry, NULL);

  printf("In MainThread\n");
  pthread_join(tid,NULL);
  
  size_t i = 0;
  for(; i<sizeof(arr)/sizeof(arr[0]); ++i)
  {
    printf("%d\n",arr[i]);
    sleep(1);
  }

  return 0;
}

4.分离线程

  • 默认情况下,新创建的线程是joinable的,线程退出后,需要对其进行pthread_join操作,否则无法释 放资源,从而造成系统泄漏。
  • 如果不关心线程的返回值,join是一种负担,这个时候,我们可以告诉系统,当线程退出时,自动释放 线程资源。
  • int pthread_detach(pthread_t thread);
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>

int arr[100000000] = {0};
void* ThreadEntry(void* arg)
{
  (void)arg;
  size_t i = 0;
  for(; i<sizeof(arr)/sizeof(arr[0]); ++i)
  {
    arr[i] = i;
  }

  return NULL;
}

int main()
{
  pthread_t tid;
  pthread_create(&tid,NULL,ThreadEntry, NULL);

  printf("In MainThread\n");
  pthread_detach(tid);
  size_t i = 0;
  for(; i<sizeof(arr)/sizeof(arr[0]); ++i)
  {
    printf("%d\n",arr[i]);
    sleep(1);
  }
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值