[Linux用户空间编程-7]:pThread线程库-线程管理代码示例

本文详细介绍了在Linux环境下如何管理线程,包括设置或获取线程调度参数、绑定线程到特定CPU核心以及创建线程。通过示例函数展示了如何使用pthread库进行线程属性设置、调整优先级和核心绑定。此外,还提供了查看当前线程运行的CPU核心信息的方法。
摘要由CSDN通过智能技术生成

作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客

本文网址:https://blog.csdn.net/HiWangWenBing/article/details/124063774


目录

第1章 头文件

第2章 设置或获取线程属性

第3章 绑定Core

第4章 创建线程


第1章 头文件

#ifndef _MY_THREAD_H_
#define _MY_THREAD_H_
    
#ifdef __cplusplus
    extern "C" {
#endif
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <pthread.h>

/*** Definition ***/
#define  APP_THREAD_CNT          32

#define  THREAD_PRI_DEMO        60

#define true   1
#define false  0

typedef enum
{
    COORE_ALL=-1,
    CORE0=0,
    CORE1,
    CORE2,
    CORE3,
    CORE4,
    CORE5,
    CORE6,
    CORE7,
    CORE8,
    CORE9,
    CORE10,
} CORE_ID;

/*** Data Structure ***/
typedef unsigned char   UINT8;
typedef unsigned short  UINT16;
typedef unsigned int      UINT32;

typedef void * (* ThreadFunction_t) (void*);

typedef struct thread_queue_info_struct_t
{
    bool                          valid;
    const char                *pName;
    ThreadFunction_t 	 entry;
    UINT32			 policy;
    UINT32			 priority;
    CORE_ID                   core;
} THREAD_QUEUE_INFO;

/*** Funtion Call ***/
// Demo thread
void *demo_thread(void *);
void * demo_dumy(void *);

// Thread attributes
int GetSelfThreadSchedParam(int *pPolicy, int *pPriority);
int SetSelfThreadSchedParam(int policy, int priority);
void DisplayPthreadAttribute(pthread_t *pTid, pthread_attr_t *attr);
int SetThreadPriority(pthread_attr_t *pAttr, int priority);


//Bind Core
int BindTidThreadToCore(pthread_t tid, int core_id);
int BindCurrentThreadToCore(int core_id);
void DisplaySelfThreadCores(void);

//Create Thread
int CreateNormalThread(pthread_t *pTid, ThreadFunction_t function, int priority);
int CreateCustomizedThread(pthread_t *pTid, const char *pName, ThreadFunction_t pThreadEntry, UINT32 policy, UINT32 priority, CORE_ID core);
void CreateBatchThreads(void);

#ifdef __cplusplus
    }
#endif /* __cplusplus */
#endif /* _OSA_THREAD_H_ */

第2章 设置或获取线程属性

int GetSelfThreadSchedParam(int *pPolicy, int *pPriority)
{
    struct sched_param param;
    int local_policy;
    
    pthread_t tid = pthread_self();

    if(pthread_getschedparam(tid, &local_policy, &param))
    {
        printf("pthread_getschedparam failed, tid=%u\n", (unsigned int)tid);
	return -1;
    }
    else
    {
    	*pPolicy = local_policy;
    	*pPriority = param.sched_priority;
    	printf("pThread [%u] get policy[%d] priority[%d]\n",  (unsigned int) tid,  local_policy, param.sched_priority);
    	return 0;
    }
}


int SetSelfThreadSchedParam(int policy, int priority)
{
    struct sched_param param;
    int local_policy;
    
    pthread_t tid = pthread_self();

    if(pthread_getschedparam(tid, &local_policy, &param))
    {
        printf("pthread_getschedparam failed, tid=%ld\n", tid);
        return -1;
    }
    printf("pThread [%lu] get policy[%d] priority[%d] before set\n", tid,  local_policy, param.sched_priority);

    param.sched_priority = priority;
    local_policy = policy;
    if(pthread_setschedparam(tid, local_policy, &param))
    {
		printf("pthread_setschedparam failed, tid=%lu\n", tid);
        return -1;
    }

    if(pthread_getschedparam(tid, &local_policy, &param))
    {
        printf("pthread_getschedparam failed, tid=%ld\n", tid);
        return -1;
    }
    printf("pThread [%lu] get policy[%d] priority[%d] after set\n", tid, local_policy, param.sched_priority);
    return 0;
}


void DisplayPthreadAttribute(pthread_t *pTid, pthread_attr_t *attr)
{
    int status, value;
    size_t size;
    void *stkaddr;
    struct sched_param sp;
 
    printf("Thread Attributes for tid=%u:\n", (unsigned int)(*pTid));
    //get the detachstate
    status = pthread_attr_getdetachstate(attr, &value);
    if (status != 0)
    {
        printf("pthread_attr_getdetachstate error=%d!\n", status);
    }
    
    printf("\tDetach state        = %s\n",
        (value == PTHREAD_CREATE_DETACHED) ? "PTHREAD_CREATE_DETACHED" :
        (value == PTHREAD_CREATE_JOINABLE) ? "PTHREAD_CREATE_JOINABLE" :
        "???");

    //get the scope
    status = pthread_attr_getscope(attr, &value);
    if (status!= 0)
    {
        printf("pthread_attr_getscope error=%d!\n", status);
    }
    
    printf("\tScope               = %s\n",
        (value == PTHREAD_SCOPE_SYSTEM)  ? "PTHREAD_SCOPE_SYSTEM" :
        (value == PTHREAD_SCOPE_PROCESS) ? "PTHREAD_SCOPE_PROCESS" :
        "???");

    //get the inheritsched
    status = pthread_attr_getinheritsched(attr, &value);
    if (status != 0)
    {
        printf("pthread_attr_getinheritsched error=%d!\n", status);
    }
    printf("\tInherit scheduler   = %s\n", 
        (value == PTHREAD_INHERIT_SCHED)  ? "PTHREAD_INHERIT_SCHED" :
        (value == PTHREAD_EXPLICIT_SCHED) ? "PTHREAD_EXPLICIT_SCHED" :
        "???");

    // get the policy
    status= pthread_attr_getschedpolicy(attr, &value);
    if (status != 0)
    {
        printf("pthread_attr_getschedpolicy error=%d!\n", status);
    }
    printf("\tScheduling policy   = %s\n",
        (value== SCHED_OTHER) ? "SCHED_OTHER" :
        (value== SCHED_FIFO)  ? "SCHED_FIFO" :
        (value == SCHED_RR)    ? "SCHED_RR" :
        "???");

    //get the schedparam: sched_priority
    status = pthread_attr_getschedparam(attr, &sp);
    if (status != 0)
    {
        printf("pthread_attr_getschedparam error=%d!\n", status);
    }
    printf("\tScheduling priority = %d\n", sp.sched_priority);

    //get the guardsize of stack
    status= pthread_attr_getguardsize(attr, &size);
    if (status != 0)
    {
        printf("pthread_attr_getguardsize error=%d!\n", status);
    }
    printf("\tGuard size          = %lu bytes\n", size);

    //get the stack 
    status= pthread_attr_getstack(attr, &stkaddr, &size);
    if (status != 0)
    {
        printf("pthread_attr_getstack error=%d!\n", status);
    }
    printf("\tStack address       = %p\n", stkaddr);
    printf("\tStack size           = %lu bytes\n", size);
}

int SetThreadPriority(pthread_attr_t *pAttr, int priority)
{
    struct sched_param param;
    int policy;
    int min, max; // thread priority

    //Get the current schedparams of scheduler
    if (pthread_attr_getschedparam(pAttr, &param))
    {
        printf("pthread_attr_getschedparam failed\n");
        return -1;
    }

    /* Get  current policy of scheduler */
    if (pthread_attr_getschedpolicy(pAttr, &policy))
    {
        printf("pthread_attr_getschedpolicy failed\n");
        return -1;
    }

    // get max priority based on policy
    max = sched_get_priority_max(policy);
    
    if (priority > max) 
    {
        printf("priority(%d) is higher than max(%d)\n", priority, max);
        priority = max;
    }
    // min priority
    min = sched_get_priority_min(policy);
    if (priority < min)
    {
        printf("priority(%d) is lower than min(%d)\n", priority, min);
        priority = min;
    }
    
    // set priority of scheduler
    param.sched_priority = priority;
    if (pthread_attr_setschedparam(pAttr, &param))
    {
        printf("pthread_attr_setschedparam failed\n");
        return -1;
    }
    //printf("pthread_attr_setschedparam successfully: priority=%d for policy=%d\n", priority, policy);

    return 0; // success
}

第3章 绑定Core

int BindTidThreadToCore(pthread_t tid, int core_id)
{
    int ret;
    int num_cores = sysconf(_SC_NPROCESSORS_ONLN);
    
    cpu_set_t cpuset;

    //check the numbers of valid cores
    if ((0 > core_id) || (num_cores <= core_id))
    {
        return EINVAL;
    }

    //prepare the cpu_set_t
    CPU_ZERO(&cpuset);
    CPU_SET(core_id, &cpuset);

    //bind tid to cpu set
    ret = pthread_setaffinity_np(tid, sizeof(cpu_set_t), &cpuset);

    printf("Bind Thread %lu to core Core %d, num_cores=%d , status=%d\n", tid, core_id, num_cores, ret);
    return ret;
}

int BindCurrentThreadToCore(int core_id)
{
    int ret;
    pthread_t current_thread = pthread_self();
    
    ret = BindTidThreadToCore(current_thread, core_id);
    
    return ret;
}


void DisplaySelfThreadCores(void)
{
    int status;
    cpu_set_t cpuset;
    pthread_t current_thread = pthread_self();
    
    CPU_ZERO(&cpuset);

    status = pthread_getaffinity_np(current_thread, sizeof(cpuset), & cpuset) ;
    if (status!= 0)
    {
        printf("sched_getaffinity error=%d!\n", status);
    }
    
    int cpus = sysconf(_SC_NPROCESSORS_CONF);
    char sbuf[128];
    char *ptr = sbuf;
    memset(sbuf, sizeof(sbuf), 0);
    
    for(int i = 0; i < cpus; i++)
    {
        if (CPU_ISSET(i, &cpuset))
        {
           ptr +=sprintf(ptr, " %d,", i);
        }
    }
    printf("The thread %lu run on processor: %s\n", current_thread, sbuf);
}

第4章 创建线程

int CreateCustomizedThread(pthread_t *pTid, const char *pName, ThreadFunction_t pThreadEntry, UINT32 policy, UINT32 priority, CORE_ID core)
{
    pthread_attr_t  attr;
    pthread_t tid;
    struct sched_param param;
    int local_policy;
    int ret = 0;

    //make the intial attribute for thread
    ret = pthread_attr_init(&attr);
    if(ret != 0)
    {
        printf("pthread_attr_init\n");
        return ret;
    }

    //set detach state of thread
    ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    if(ret != 0)
    {
        printf("pthread_attr_setdetachstate fail\n");
        return ret;
    }

    //set policy and priority of thread
    if((policy == SCHED_RR) || (policy == SCHED_RR))
    {
        ret = pthread_attr_setschedpolicy(&attr, policy);
        if(ret != 0)
        {
            printf("pthread_attr_setschedpolicy fail\n");
            return ret;
        }

        ret = SetThreadPriority(&attr, priority);
        if(ret != 0)
        {
            printf("SetThreadPriority fail\n");
            return ret;
        }
    }
    
    //create thread
    ret = pthread_create(&tid, &attr, pThreadEntry, NULL);
    if(ret != 0)
    {
        printf("pthread_create fail\n");
        return ret;
    }

    //save tid of thread
    memcpy(pTid, &tid, sizeof(pthread_t));

   //DisplayPthreadAttribute(&tid, &attr);

    //set the thread name
    if(pName != NULL)
    {
        printf("set pthread %lu with name %s\n", tid, pName);

        //must be self?
        ret = pthread_setname_np(tid, pName);
        if(ret !=0)
        {
            printf("pthread_setname_np fail\n");
            return ret;
        }
    }

    //bind core
    if(core >= 0)
    {
        ret = BindTidThreadToCore(tid, core);
        if(ret != 0)
        {
            printf("BindTidThreadToCore fail\n");
            return ret;
        }
    }
    
    return ret;
}

作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客

本文网址:https://blog.csdn.net/HiWangWenBing/article/details/124063774

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

文火冰糖的硅基工坊

你的鼓励是我前进的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值