关于std 线程库 优先级问题 以及linux 线程优先级设置不生效问题记录

2023-12-20 14:43:08

一、标准线程库thread 并不支持设置优先级等属性,,如果需要设置需要使用系统相关的API 进行设置,使用 native_handle? 函数进行对接。

二、linux 线程优先级 设置后执行顺序不是预期行为?,考虑是不是多核CPU 导致。可以设置线程亲和性后进行测试。

三、如下提供了使用 std:thread 和 std:async 进行多线程处理的实例,并且测试了使用pthread 的API 设置线程优先级和调度策略。多核CPU 下设置亲和性后,输出与预期一致。如何设置为实时线程,需root用户运行程序。

thread.cpp

#include <iostream>
#include <thread>
#include <pthread.h>
#include <sched.h>
#include <vector>
#include <chrono>
#include <unistd.h>  
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
using namespace std::chrono_literals;

void thread_func(int id)
{
     std::cout << "Thread " << id << " started." << std::endl;

    sleep(2); //保证所有线程都启动设置完
   
    long num = 0;
    for (int i = 0; i < 10; i++)
    {
        for (int j = 0; j < 5000000; j++)
        {
            // 没什么意义,纯粹是模拟 CPU 密集计算。
            float f1 = ((i+1) * 345.45) * 12.3 * 45.6 / 78.9 / ((j+1) * 4567.89);
            float f2 = (i+1) * 12.3 * 45.6 / 78.9 * (j+1);
            float f3 = f1 / f2;
        }
        
        // 打印计数信息,为了能看到某个线程正在执行
        printf("thread_index %d: num = %ld \n", id, num++);
    }

}
int main()
{

    std::vector<std::thread> threads;
    for(int i = 0; i < 10; i++) {
        threads.emplace_back(std::thread(thread_func, i));        
    }

    for(int i = 0; i < 10; i++) {
        pthread_t thread_handle = threads[i].native_handle();

        //设置亲和性
        cpu_set_t mask;
        int cpus = sysconf(_SC_NPROCESSORS_CONF);
        CPU_ZERO(&mask);
        CPU_SET(0, &mask);
        if (pthread_setaffinity_np(thread_handle, sizeof(mask), &mask) < 0)
        {
            printf("set thread affinity failed! \n");
        }

        // 修改线程的调度策略和优先级
        int policy = SCHED_RR; // 设置为轮流调度
        int priority = 10; // 设置优先级为 10
        pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_attr_setschedpolicy(&attr, policy);
        sched_param param;
        param.sched_priority = priority;
        pthread_attr_setschedparam(&attr, &param);
        pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); //设置分离属性
        
        pthread_setschedparam(thread_handle, policy, &param);

        
    }
    for(int i = 0; i < 10; i++) {
        threads[i].join();
    }

    std::this_thread::sleep_for(8000ms); 
        
    return 0;
}

async.cpp


#include <iostream>
#include <future>
#include <vector>
#include <unistd.h>  
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
#include <pthread.h>
void worker(int id) {
    std::cout << "Thread " << id << " started." << std::endl;

    //设置亲和性
    pthread_t thread = pthread_self();
    cpu_set_t mask;
    int cpus = sysconf(_SC_NPROCESSORS_CONF);
    CPU_ZERO(&mask);
    CPU_SET(0, &mask);
    if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0)
    {
        printf("set thread affinity failed! \n");
    }

    // 修改线程的调度策略和优先级
    int policy = SCHED_FIFO; // 设置为抢占调度
    int priority = 10+id; // 设置优先级为 10
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setschedpolicy(&attr, policy);
    sched_param param;
    param.sched_priority = priority;
    pthread_attr_setschedparam(&attr, &param);
    pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); //设置分离属性
 
    pthread_setschedparam(pthread_self(), policy, &param);


    sleep(1);
   
    long num = 0;
    for (int i = 0; i < 10; i++)
    {
        for (int j = 0; j < 5000000; j++)
        {
            // 没什么意义,纯粹是模拟 CPU 密集计算。
            float f1 = ((i+1) * 345.45) * 12.3 * 45.6 / 78.9 / ((j+1) * 4567.89);
            float f2 = (i+1) * 12.3 * 45.6 / 78.9 * (j+1);
            float f3 = f1 / f2;
        }
        
        // 打印计数信息,为了能看到某个线程正在执行
        printf("thread_index %d: num = %ld \n", id, num++);
    }


    std::cout << "Thread " << id << " changed." << std::endl;
}
int main() {
  std::cout << "Main thread started." << std::endl;
  std::vector<std::future<void>> futures;
  for(int i = 0; i < 10; i++) {
    futures.emplace_back(std::async(std::launch::async, worker, i));
  }
  for(auto& f : futures) {
    f.get();
  }
  std::cout << "Main thread finished." << std::endl;
  return 0;
}

文章来源:https://blog.csdn.net/HUANG_XIAOJUN/article/details/135106559
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。