线程绑定核,线程调度属性

本文介绍如何使用pthread_setaffinity_np和sched_setaffinity设置线程的CPU亲和性,并通过pthread_attr_setschedpolicy等函数调整线程的调度策略及优先级。

1、pthread_setaffinity_np

#include <pthread.h> 
#include <sched.h>

        cpu_set_t mask; 
        cpu_set_t get; 

        CPU_ZERO(&mask); 
        CPU_SET(i, &mask);  // i is cpu core id
        if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0) { 
            fprintf(stderr, "set thread affinity failed\n"); 
        } 
        CPU_ZERO(&get); 
        if (pthread_getaffinity_np(pthread_self(), sizeof(get), &get) < 0) { 
            fprintf(stderr, "get thread affinity failed\n"); 
        } 
        for (j = 0; j < num; j++) { 
            if (CPU_ISSET(j, &get)) { 
                printf("thread %d is running in processor %d\n", (int)pthread_self(), j); 
            } 
        } 

2、sched_setaffinity

       CPU_ZERO(&mask); 
       CPU_SET(myid, &mask); 

      if (sched_setaffinity(0, sizeof(mask), &mask) == -1)  // 0 表示当前线程
        { 
                printf(“warning: could not set CPU affinity, continuing…\n”); 
        } 


3、设置线程调度模式和优先级

#include <pthread.h> 
#include <sched.h> 
int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched);  
void pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);  
int pthread_attr_setschedparam(pthread_attr_t *restrict attr,  
                         const struct sched_param *restrict param); 

inheritsched可以为如下值。
PTHREAD_INHERIT_SCHED:线程调度属性是从创建者线程继承得到,attr的任何调度属性都被忽略。
PTHREAD_EXPLICIT_SCHED:线程调度属性设置为属性对象attr的调度属性。


policy的值可以为在<sched.h>头文件中定义的以下值。
SCHED_FIFO:先进先出调度策略,执行线程运行到结束。// 除非阻塞或主动切换,否则不释放CPU
SCHED_RR:轮询调度策略,按照时间片将每个线程分配到处理器上。
SCHED_OTHER:另外的调度策略(根据实现定义)。这是任何新创建线程的默认调度策略。


sched_param结构体至少需要定义这个数据成员:
struct sched_param {  
   int sched_priority;  
   //...  
}; 
它可能还有其他的数据成员,以及多个用来返回和设置最小优先级、最大优先级、调度器、参数等的函数。如果调度策略是SCHED_FIFO或SCHED_RR,那么要求具有值的唯一成员是sched_priority。


按照如下方法使用sched_get_priority_max( )和sched_get_priority_max( ),可以得到优先级的最大值和最小值。
int sched_get_priority_max(int policy);  
int sched_get_priority_min(int policy); 


pthread_t ThreadA;  
pthread_attr_t SchedAttr;  
sched_param SchedParam;  
int MidPriority,MaxPriority,MinPriority;  

  // Step 1: initialize attribute object  
   pthread_attr_init(&SchedAttr);  
 
   // Step 2: retrieve min and max priority values for scheduling policy  
   MinPriority = sched_get_priority_max(SCHED_RR);  
   MaxPriority = sched_get_priority_min(SCHED_RR);  
 
   // Step 3: calculate priority value  
   MidPriority = (MaxPriority + MinPriority)/2;  
 
   // Step 4: assign priority value to sched_param structure  
   SchedParam.sched_priority = MidPriority;  
 
   // Step 5: set attribute object with scheduling parameter  
   pthread_attr_setschedparam(&SchedAttr, &SchedParam);  
 
   // Step 6: set scheduling attributes to be determined by attribute object  
   pthread_attr_setinheritsched(&SchedAttr, PTHREAD_EXPLICIT_SCHED);  
 
   // Step 7: set scheduling policy  
   pthread_attr_setschedpolicy(&SchedAttr,SCHED_RR);  
 
   // Step 8: create thread with scheduling attribute object  
   pthread_create(&ThreadA,&SchedAttr,task1,NULL);  


在Zephyr操作系统中,设置线程的CPU亲和性(即绑定线程到特定的CPU心)可以通过以下方式进行: Zephyr支持多架构,并为线程调度提供了对CPU亲和性的控制机制。开发者可以使用线程属性来指定线程应当运行在哪一个或哪些CPU心上。具体而言,可以通过`k_thread_attr_t`结构体中的`cpumask`字段来定义线程的CPU亲和性。 以下是设置线程CPU亲和性的典型步骤和代码示例: ```c #include <zephyr.h> #include <sys/printk.h> #include <shell/shell.h> #include <stdlib.h> void thread_entry(void *p1, void *p2, void *p3) { uint32_t target_cpu = (uint32_t)p1; printk("Thread running on CPU %u\n", target_cpu); /* 线程主循环 */ while (1) { /* 模拟工作 */ k_msleep(1000); } } int cmd_set_affinity(const struct shell *shell, size_t argc, char **argv) { uint32_t cpu_id; struct k_thread thread; k_thread_stack_t *stack; k_thread_attr_t attr = {0}; if (argc < 2) { shell_error(shell, "Please specify a CPU ID."); return -EINVAL; } cpu_id = atoi(argv[1]); /* 分配线程栈 */ stack = k_thread_stack_alloc(512, 4); if (!stack) { shell_error(shell, "Failed to allocate thread stack."); return -ENOMEM; } /* 设置线程属性 */ attr.stack = stack; attr.stack_size = 512; attr.thread_options = K_USER | K_INHERIT_PERMS; /* 设置CPU亲和性 */ attr.cpumask = 1U << cpu_id; /* 创建线程 */ k_thread_create(&thread, stack, attr.stack_size, thread_entry, (void *)(uintptr_t)cpu_id, NULL, NULL, K_PRIO_COOP(10), attr.thread_options, K_FOREVER); k_thread_start(&thread); shell_print(shell, "Thread created and bound to CPU %u", cpu_id); return 0; } SHELL_CMD_ARG_REGISTER(set_affinity, NULL, "Set thread affinity to a specific CPU core", cmd_set_affinity, 2, 0); ``` ### 说明: 1. **线程属性设置**:通过`k_thread_attr_t`结构体,可以定义线程属性,包括CPU亲和性掩码(`cpumask`)。掩码通过位操作指定线程允许运行的CPU心,例如`1U << cpu_id`表示绑定到特定CPU心。 2. **线程创建**:使用`k_thread_create`函数创建线程时,传入配置好的属性线程将仅在指定的CPU心上运行。 3. **动态调整**:如果需要在运行时更改线程的CPU亲和性,可以使用`k_thread_cpu_mask_clear`和`k_thread_cpu_mask_set`等函数进行调整。 ### 注意事项: - 确保目标CPU心已启用,并且系统支持多架构。 - 线程的优先级和调度策略也会影响其实际运行的CPU心,因此需要结合系统整体调度策略进行考虑。 - 在多系统中,需要特别注意共享资源的同步问题,以避免竞态条件。 通过上述方式,可以在Zephyr操作系统中实现线程的CPU亲和性设置,从而更好地控制线程的执行环境。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值