Linux C system programming (11) thread management thread control

Thread control: Setting the attributes of a thread is an advanced operation. This attribute affects the behavior of the kernel, so these attributes are generally not modified, especially the size of the thread kernel stack.


1 Create and destroy attribute structure

When using the pthread_create function to create a thread, you can set the attribute of the thread through the second parameter attr, set to NULL to use the system default attributes to create the thread, the thread attributes are organized in a structure. The structure is as follows:

//线程属性结构
typedef struct
{
   int                detachstate;   //线程的分离状态
   int                schedpolicy;   //线程调度策略
   struct sched_param schedparam;    //线程的调度参数
   int                inheritsched;  //线程的继承性
   int                scope;         //线程的作用域
   size_t             guardsize;     //线程栈末尾的警戒缓冲区大小
   int                stackaddr_set;
   void *             stackaddr;     //线程栈的位置
   size_t             stacksize;     //线程栈的大小
}pthread_attr_t;

Use pthread_attr_init to initialize the attribute structure, use pthread_attr_destroy function to destroy an unused attribute structure. The function prototype is as follows:

//pthread_attr_init 函数为属性结构分配内存空间,通过这个参数返回首地址。
int pthread_attr_init (pthread_attr_t *attr);
//pthread_attr_destroy将前者分配的内存空间释放;
int pthread_attr_destroy (pthread_attr_t *attr);
参数attr:一个指向线程属性结构的指针。
函数执行成功返回0,失败返回错误号。

Note: The two must appear together, otherwise it will cause a memory leak (one is address allocation and the other is address release).


2 Thread attributes

2.1 Thread separation state

Thread separation status: Determine how a thread terminates itself. There are two states:

  1. Non-detached state (default): At this time, the original thread waits for the end of the created thread. Only when the pthread_join () function returns, the created thread is terminated and the system resources occupied by it can be released.
  2. Separation state: The separation thread is not waited for by other threads. When the operation is finished, the thread is terminated and the system resources are released immediately.

Use pthread_attr_getdetachstate to get the detached state of the thread, and pthread_attr_setdetachstate to set the detached state of the thread. The function prototype is as follows:

int pthread_attr_getdetachstate(const pthread_attr_t *attr,int *detachstate);
int pthread_attr_setdetachstate(pthread_attr_t *attr,intdetachstate);
参数:
Attr   线程属性变量
Detachstate  线程的分离状态属性,有两个值
    PTHREAD_CREATE_DETACHED,以分离状态启动线程;
    PTHREAD_CREATE_JOINABLE,以非分离状态启动线程;
返回值:若成功返回0,若失败返回-1。

Instructions for use: If we know that we do not need to know the termination state of the thread when creating the thread, we can use the detachstate thread attribute in the pthread_attr_t structure to let the thread start in a detached state.

2.2 Stack settings

When pthread_create creates a thread, if you do not specify the size of the allocated stack, the system will assign a default value. The method for viewing the default value is as follows:

ulimit -s

Use pthread_attr_getstacksize to get the thread's stack size, use pthread_attr_setstacksize to set the thread's stack size. The function prototype is as follows:

int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize);
参数:
attr            线程属性变量
inheritsched    线程的栈大小,stacksize以字节为单位
返回值:若成功返回0,若失败返回

In terms of personal career scope, this setting is mainly in the embedded environment. Because the memory is not very large in the embedded, using the default value will cause insufficient memory, so you need to set this stack in advance before creating a thread.

2.3 Scheduling strategy

Thread scheduling policy can be set through API, use pthread_attr_getschedpolicy to obtain scheduling policy, use pthread_attr_setschedpolicy to set scheduling policy. The function prototype is as follows:

int pthread_attr_getschedpolicy(const pthread_attr_t*attr,int *policy);
int pthread_attr_setschedpolicy(pthread_attr_t *attr,intpolicy);
参数:
attr           线程属性变量
policy         调度策略
	SCHED_FIFO(先进先出),支持优先级1-99
	SCHED_RR(轮转法),支持优先级1-99
	SCHED_OTHER(其它),不支持优先级
返回值:
若成功返回0,若失败返回-1。

Detailed description of SCHED_FIFO and SCHED_RR strategies:

  1. SCHED_FIFO strategy: It will start execution soon, unless there is a higher priority thread already running or blocking itself.
  2. SCHED_RR (round robin) strategy: set time slices.

note:

  1. If a SCHED_RR policy thread executes for more than a fixed period (time slice interval) without blocking, and another SCHED_RR or SCHBD_FIPO policy thread of the same priority is ready, the running thread will be preempted in order to prepare the thread Can be executed.
  2. When threads with the SCHED_FIFO or SCHED_RR policy hold or wait on a condition variable and lock the same mutex, they will be woken up in order of priority. That is, if a low-priority SCHED_FIFO thread and a high-priority SCHED_FIFO thread are both waiting for the same mutex lock, then when the mutex is unlocked, the high-priority thread will always be unblocked first.

2.4 Scheduling parameters

Thread scheduling parameters can be set through the API, use pthread_attr_getschedparam to obtain scheduling parameters, use pthread_attr_setschedparam to set scheduling parameters. The function prototype is as follows:

int pthread_attr_getschedparam(const pthread_attr_t*attr,struct sched_param *param);
int pthread_attr_setschedparam(pthread_attr_t *attr,conststruct sched_param *param);
参数:
attr           线程属性变量
param          sched_param结构
返回值:若成功返回0,若失败返回-1。

This involves a structure sched_param, which is implemented as follows:

struct sched_param
{
    int sched_priority; // 该参数的本质就是优先级
};

The sched_priority child member of the structure sched_param controls a priority value (the larger the value, the higher the priority). The maximum and minimum priority values ​​supported by the system can be obtained using the sched_get_priority_max function and the sched_get_priority_min function, respectively.

Special note: If you are not writing a real-time program, it is not recommended to modify the priority of the thread. If the scheduling strategy is not used correctly, it will lead to program errors, leading to various problems such as deadlock. For example, in a multi-threaded application, setting different priority levels for threads may lead to inversion of priorities due to shared resources.

2.5 Inheritance

Inheritance determines whether the scheduling parameters are inherited from the created process or use the scheduling information explicitly set in the schedpolicy and schedparam attributes. Use pthread_attr_getinheritsched to obtain inheritance information, use pthread_attr_setinheritsched to set inheritance information. The corresponding function prototype is as follows:

int pthread_attr_getinheritsched(const pthread_attr_t*attr,int *inheritsched);
int pthread_attr_setinheritsched(pthread_attr_t *attr,intinheritsched);
参数:
attr            线程属性变量
inheritsched    线程的继承性
    PTHREAD_INHERIT_SCHED表示新现成将继承创建线程的调度策略和参数
    PTHREAD_EXPLICIT_SCHED表示使用在schedpolicy和schedparam属性中显式设置的调度策略和参数
返回值:若成功返回0,若失败返回-1。

Pthreads does not specify a default value for inheritsched, if you are concerned about the scheduling strategy and parameters of the thread, you must first set this attribute.


3 pthread series function query method

There are many functions on the pthread series. If used, we can not directly use the man command under Linux to query, but install the pthread thread man page manual. The installation commands are as follows:

sudo apt-get install manpages-posix-dev

Verify the installation:

man -k pthread 

You can list pthreads. View the current version of the pthread library:

getconf GNU_LIBPTHREAD_VERSION

When using the thread library, gcc compilation needs to add -lpthread (lowercase L)

Published 289 original articles · praised 47 · 30,000+ views

Guess you like

Origin blog.csdn.net/vviccc/article/details/105166567