Linux multithreaded programming | thread attributes

Thread attributes

The second parameter (pthread_attr_t *attr) of the thread creation function pthread_create() represents the attributes of the thread. Generally set to NULL to indicate the default attributes (non-binding, non-separation, default 1MB stack and the same priority as the parent process). Many attributes of a thread can be changed. These attributes mainly include binding attributes, separation attributes, stack address, stack size and priority. The following describes the basic concepts of binding properties and separating properties

1. Binding properties

Linux uses a "one-to-one" threading mechanism, that is, a user thread corresponds to a kernel thread. The binding attribute means that a user thread is fixedly allocated to a kernel thread. Because the scheduling of CPU time slices is oriented to the kernel thread, the thread with the binding attribute can ensure that there is always a kernel thread corresponding to it when needed. The non-binding attribute means that the relationship between user threads and kernel threads is not always fixed, but the system controls the allocation

2. Separation of attributes

The separation attribute is used to determine how a thread terminates itself. In the case of non-separation, when the thread ends, the system resources it occupied are not released, that is, it is not really terminated. Only when the pthread_join() function returns, the created thread can release the occupied system resources. Under the detached attribute, the system resources occupied by the thread are immediately released when the thread ends

3. Property setting function

The settings of these properties are done through specific functions

  • First call the pthread_attr_init() function to initialize, then call the attribute setting function
  • Set binding attributes, use pthread_attr_setscope() function
  • To set the detached attribute, use the pthread_attr_setdetachstate() function
  • Set priority, use pthread_attr_getschedparam() function to get priority, then use phread_attr_setschedparam() function to set priority
  • After the properties are set, use the pthread_create() function to create a thread

pthread_attr_init()

/*****pthread_attr_init()*****/
函数原型:int pthread_attr_init(pthread_attr_t *attr)
传 入 值:attr 线程属性结构指针
返 回 值:成功返回0;失败返回错误码

pthread_attr_setscope()

/*****pthread_attr_setscope()*****/
函数原型:int pthread_attr_setscope(pthread_attr_t *attr, int scope)
传 入 值:attr 线程属性结构指针
		 scope -->PTHREAD_SCOPE_SYSTEM 绑定
		       -->PTHREAD_SCOPE_PROCESS 非绑定
返 回 值:成功返回0;失败返回-1

pthread_attr_setdetachstate()

/*****pthread_attr_setdetachstate()*****/
函数原型:int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
传 入 值:attr 线程属性结构指针
		 detachstate -->PTHREAD_CREATE_DETACHED 分离
		             -->PTHREAD_CREATE_JOINABLE 非分离
返 回 值:成功返回0;失败返回错误码

pthread_attr_getschedparam()

/*****pthread_attr_getschedparam()*****/
函数原型:int pthread_attr_getschedparam(pthread_attr_t *attr, struct sched_param *param)
传 入 值:attr 线程属性结构指针
		 param 线程优先级
返 回 值:成功返回0;失败返回错误码

pthread_attr_setschedparam()

/*****pthread_attr_setschedparam()*****/
函数原型:int pthread_attr_setschedparam(pthread_attr_t *attr, struct sched_param *param)
传 入 值:attr 线程属性结构指针
		 param 线程优先级
返 回 值:成功返回0;失败返回错误码

4. Function Examples

Create a thread with binding and detaching properties, and the main thread gets the message of the end of the thread through a finish_flag flag variable

/*****thread_attr.c*****/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define REPEAT_NUMBER 5		//每个线程中的小任务数
#define DELAY_TIME_LEVELS 10.0  //小任务之间的最大时间间隔
int finish_flag = 0;

void *thrd_func(void *arg){
    
    
	int delay_time = 0,count = 0;	
	printf("Thread is starting\n");
	for(count = 0;count < REPEAT_NUMBER;count++){
    
    
		delay_time = (int)(rand()*DELAY_TIME_LEVELS/(RAND_MAX)) + 1;
		sleep(delay_time);
		printf("\tThread: job %d delay = %d\n",count,delay_time);
	}
	printf("Thread finished\n");
	finish_flag = 1;
	pthread_exit(NULL);
}

int main(){
    
    
	pthread_t thread;
	pthread_attr_t attr;
	int no = 0,res;
	void * thrd_ret;

	srand(time(NULL));
	res = pthread_attr_init(&attr);	//初始化线程属性对象
	if(res != 0){
    
    
		printf("Create attribute failed\n",no);
		exit(res);
	}
	res = pthread_attr_setscope(&attr,PTHREAD_SCOPE_SYSTEM);	//设置绑定属性
	res+ = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHDE);	//设置分离属性
	if(res != 0){
    
    
		printf("Setting attribute failed\n",no);
		exit(res);
	}
	res = pthread_create(&thread, &attr, thrd_func, NULL);
	if(res != 0){
    
    
		printf("Create thread failed\n",no);
		exit(res);
	}

	pthread_attr_destory(&attr)		//释放线程属性对象
	printf("Create thread sucess\n");
	while(!finish_flag){
    
    
		printf("Waiting for thread to finish...\n");
		sleep(2)
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/Chuangke_Andy/article/details/108357669