线程管理(三)

线程ID、线程属性、线程撤销
线程ID

pthread_equal()函数:确认两个线程是否相同

  • 原型
int pthread_equal(pthread_t t1, pthread_t t2);

pthread_self()函数:返回当前线程ID

  • 原型:
pthread_t pthread_self(void);
  • 示例
  if (!pthread_equal (pthread_self (), other_tid))
    {
      pthread_join (other_tid, nullptr);
    }
线程属性

精细调整线程的行为

设置线程属性的流程

  • 创建pthread_attr_t类型的对象

  • 调用pthread_attr_init()函数初始化线程缺省属性,传递指向该线程属性对象的指针

    原型:

    int pthread_attr_init(pthread_attr_t *attr);
    
  • 对线程属性进行必要修改

  • 调用pthread_crerate()函数时传递指向线程属性对象的指针

  • 调用pthread_attr_destroy()函数清除线程属性对象,pthread_attr_t对象本身并没有被销毁,因而可以调用pthread_attr_init()函数再次初始化

    ​ 原型:

    int pthread_attr_destroy(pthread_attr_t *attr);
    

线程属性说明

  • 单一线程属性对象可以用于创建多个线程
  • 线程创建后,继续保留线程属性对象本身并没有意义
  • 对于大多数Linux程序,线程最重要的属性为分离状态(detach state

线程分类

  • 可联线程(joinable thread): 缺省设置,终止时并不自动清除(类似僵尸进程),主线程必须调用pthread_join()获取其返回值,此后才能清除

  • 分离线程(detached thread):结束时自动清除,不能调用pthread_join()进行线程同步

  • 可联线程可通过pthread_detach()函数分离,分离线程不能再次联结

    ​ 原型:

    int pthread_detach(pthread_t thread);
    

pthread_attr_setdeatchstate()函数:设置线程分离属性

  • 原型

    int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
    
  • 传递线程属性对象指针和分离线程设置参数

    PTHREAD_CREATE_DETACHED
    

pthread_attr_getdetachstate()函数:获取线程分离属性

  • 原型

    int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
    
#include <pthread.h>

void *ThreadFunc (void *arg)
{ }

int main ()
{
  pthread_attr_t attr;
  pthread_t thread;

  //初始化线程属性
  pthread_attr_init (&attr);

  //设置线程属性的分离状态
  pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);

  //创建线程
  pthread_create (&thread, &attr, &ThreadFunc, nullptr);

  //清除线程属性对象
  pthread_attr_destroy (&attr);
  //无需联结该线程
  return 0;
}
线程撤销

pthread_cancel()函数:撤销线程

  • 原型:

    int pthread_cancel(pthread_t thread);
    
  • 已撤销的线程可以来联结,且必须联结欸,以释放其资源,除非其为分离线程

线程撤销类型与状态

  • 异步可撤销:在其执行的任何时刻都可撤销
  • 同步可撤销:线程可撤销,但撤销操作首先进入队列排队,在线程执行到特定撤销点时才可撤销
  • 不可撤销:撤销不可撤销线程的企图被系统忽略,且没有任何消息反馈

pthread_setcanceltype()函数:设置线程的撤销类型

  • 原型

     int pthread_setcanceltype(int type, int *oldtype);
    
  • 参数:

    type为撤销类型,oldtype用于保存原始线程撤销类型,NULL表示不保存

  • PTHREAD_CANCEL_ASYNCHRONOUS:线程异步可撤销

  • PTHREAD_CANCEL_DEFERRED:线程同步可撤销,即延迟到下一撤销点时撤销

pthread_setcanceltype()函数:设置线程的撤销状态

  • 原型:

    int pthread_setcanceltype(int type, int *oldtype);
    
  • 第一个参数state为可撤销状态,第二个参数oldstate用于保存原始线程的可撤销状态,NULL表示不保存

  • PTHREAD_CANCEL_ENABLE:线程可撤销

  • PTHREAD_CANCEL_DISABLE:线程不可撤销

  • 线程的撤销状态可多次设置

pthread_testcancel()函数:设置撤销点

  • 原型

     void pthread_testcancel(void);
    
  • 在线程函数中调用pthread_testcancel()函数设置撤销点

  • 建议:周期性地设置撤销点,保证线程函数内部每隔一些代码就有一个撤销点,以保证资源能够正确释放

使用撤销状态构造临界区(critical section)

  • 临界区:要么全部执行,要么一条都不会执行的代码段
  • 设置线程的撤销状态,线程一旦进入临界区,就必须等到离开临界区,才可以被撤销
void Transfer (double *accounts, int from, int to, double amount)
{
  int ocs;
  //数据有效性检查代码在此,确保转账操作合法有效

  //将线程设置为不可撤销的,进入临界区
  pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &ocs);

  accounts[to] += amount;
  accounts[from] -= accounts;

  //恢复线程的撤销状态,离开临界区
  pthread_setcancelstate (os, NULL);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值