关于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, ¶m);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); //设置分离属性
pthread_setschedparam(thread_handle, policy, ¶m);
}
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, ¶m);
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); //设置分离属性
pthread_setschedparam(pthread_self(), policy, ¶m);
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
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!