POSIX线程的属性

一、线程的属性

包括:分离状态(detached state)、调度策略和参数(scheduling policy and parameters)、作用域(scope)、栈尺寸(stack size)、栈地址(stack addree)、优先级(priority)等

Linux为线程属性定义的数据类型pthread_attr_t:

union pthread_attr_t
{
    char __size[__SIZEOF_PTHREAD_ATTR_T];
    long int __align;
};

二、对线程属性数据类型的操作函数

1、线程的默认属性

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

调用pthread_create()向第二个参数传入NULL,改线程就具有默认属性:非分离、大小为1MB的堆栈、与父进程有相同的优先级。

2、获取线程属性对象的值

#define _GNU_SOURCE             // 必须要定义的宏
#include <pthread.h>

int pthread_getattr_np(pthread_t thread, pthread_attr_t *attr);

3、创建线程时设定线程的属性

int pthread_attr_init(pthread_attr_t *attr);

作用:使用默认值初始化一个pthread_attr_t结构的非空指针

4、销毁线程属性对象

int pthread_attr_destroy(pthread_attr_t *attr);

作用:销毁一个pthread_attr_t结构的非空指针对象

三、线程属性设定

1、分离状态(detached state)

两种类型:PTHREAD_CREATE_JOINABLE 和 PTHREAD_CREATE_DETACHED

作用:

  1.  PTHREAD_CREATE_JOINABLE:表示本线程可以被同进程的其他线程使用pthread_join()来进行同步等待,并且线程的所占用的资源在被pthread_join()之后才会被释放;如果没有被同进程内的其他线程phread_join(),会造成系统资源泄露。
  2.  PTHREAD_CREATE_DETACHED:表示本线程不允许同进程的其他线程使用phread_join()进程等待返回;如果有其他进程对该线程使用pthread_join(),那么pthread_join()将会立即返回,错误码通过phread_join()的返回值返回。

操作函数:

// 设置线程的分离状态属性
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
// 获取分离状态属性
int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);

// 把一个可连接线程转变成一个可分离线程
int pthread_detach(pthread_t thread);

栗子:设置线程的分离状态属性

#include <pthread.h>
#include <stdlib.h>
#include <iostream>
#include <unistd.h>

using namespace std;

void* func(void* arg)
{
    cout << "children thread is running\n";
    return nullptr;
}

int main(int argc, char const *argv[])
{
    pthread_attr_t thread_attr;
    int rc = pthread_attr_init(&thread_attr);
    if (rc)
    {
        cout << "pthread_attr_init failed: " << rc << endl;
        return EXIT_FAILURE;
    }

    rc = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
    if (rc)
    {
        cout << "pthread_attr_setdetachstate failed: " << rc << endl;
        return EXIT_FAILURE;
    }

    pthread_t tid;
    rc = pthread_create(&tid, &thread_attr, func, nullptr);
    if (rc)
    {
        cout << "pthread_create failed: " << rc << endl;
        return EXIT_FAILURE;
    }

    cout << "main thread will exit!\n" << endl;

    sleep(1);

    return EXIT_SUCCESS;
}


执行结果:

[xy@xunye thread]$ g++ -std=c++11 detach_state.cpp -o detach_state -lpthread
[xy@xunye thread]$ ./detach_state 
main thread will exit!

children thread is running

栗子:获取线程的分离状态属性

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <pthread.h>
#include <iostream>
#include <stdlib.h>

using namespace std;

void handling_err(int err, const char* msg)
{
    errno = err;
    cerr << msg << endl;
    exit(EXIT_FAILURE);
}

void* thread_start(void* arg)
{
    pthread_attr_t attr;
    int rc = pthread_getattr_np(pthread_self(), &attr);  // 获取线程属性
    if (rc)
        handling_err(rc, "pthread_getattr_np failed.");

    cout << "Thread's detachstate attributes: " << endl;
    int detach_state = 0;
    rc = pthread_attr_getdetachstate(&attr, &detach_state);  // 获取线程分离属性
    if (rc)
        handling_err(rc, "pthread_attr_getdetachstate failed.");

    cout << "Detach state: " 
           << ((detach_state == PTHREAD_CREATE_DETACHED) ? "PTHREAD_CREATE_DETACHED" :
                (detach_state == PTHREAD_CREATE_JOINABLE) ? "PTHREAD_CREATE_JOINABLE" : "???") << endl;

    pthread_attr_destroy(&attr);  // 销毁线程属性对象
}

int main(int argc, char const *argv[])
{
    pthread_t tid;
    int rc = pthread_create(&tid, nullptr, thread_start, nullptr);
    if (rc)
        handling_err(rc, "pthread_create failed.");

    pthread_join(tid, nullptr);  // 等待子线程结束

    return 0;
}

执行结果:

[xy@xunye thread]$ g++ -std=c++11 get_detach_state.cpp -o get_detach_state -lpthread
[xy@xunye thread]$ ./get_detach_state 
Thread's detachstate attributes: 
Detach state: PTHREAD_CREATE_JOINABLE

2、栈尺寸属性

线程函数使用的局部变量不要超过栈尺寸大小。

操作函数:

int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize);

int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);

说明:attr 是线程属性变量;stacksize 则是设置的堆栈大小(单位:字节)。 成功返回值0,否则返回错误码。

3、调度策略属性

三种调度:

    1.SCHED_OTHER 分时调度策略(轮转调度策略)—— 系统默认

    2.SCHED_FIFO  实时调度策略,先到先服务。一旦占用cpu则一直运行。一直运行直到有更高优先级任务到达或自己放弃

    3.SCHED_RR实  时调度策略,时间片轮转。当进程的时间片用完,系统将重新分配时间片,并置于就绪队列尾。放在队列尾保证了所有具有相同优先级的RR任务的调度公平

操作函数:

// 获得线程可以设置的最高和最低优先级
int sched_get_priority_max(int policy);
int sched_get_priority_min(int policy);

// 设置和获取优先级
int pthread_attr_setschedparam(pthread_attr_t *attr, struct sched_param *param);
int pthread_attr_getschedparam(pthread_attr_t *attr, struct sched_param *param);

// 改变线程的调度策略
int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);

数据结构sched_param

struct sched_param
{
    int __sched_priority; // 所要设定的线程优先级
};

猜你喜欢

转载自blog.csdn.net/xunye_dream/article/details/110321620
今日推荐