#はじめに
pthreadの関数を使用して、スレッドプライオリティを設定する方法を解説していきます。
プライオリティの設定方法は、2種類あります。
- pthread_attr_tを利用してスレッド生成前に設定する
- スレッド生成後に設定する
どちらも共通して、root権限で実行しないとエラーとなります。
#1. スレッド生成前に設定する方法
流れとしては、以下のとおりです。
- pthread_attr_init()でpthread_attr_tを初期化
- pthread_attr_setinheritsched()でattrからスケジューリング属性を取得するように指定する
- pthread_attr_setschedpolicy()でスケジューリングポリシーを設定する
- pthread_attr_setschedparam()でプライオリティを設定する
以下はサンプルコードです。
#include <iostream>
#include <pthread.h>
#include <sched.h>
#define NUM_OF_THREADS 4
pthread_mutex_t mtx;
void* entry(void* arg)
{
struct sched_param param;
int policy{};
int ret = pthread_getschedparam(pthread_self(), &policy, ¶m);
if (ret != 0)
{
std::cout << "pthread_getschedparam() error[" << ret << "]\n";
}
pthread_mutex_lock(&mtx);
std::cout << "Priority:" << param.sched_priority << " start\n";
pthread_mutex_unlock(&mtx);
// do some work
return NULL;
}
int main()
{
pthread_mutex_init(&mtx, NULL);
pthread_attr_t attr;
pthread_attr_init(&attr);
int ret = pthread_attr_setinheritsched(¶m, PTHREAD_EXPLICIT_SCHED);
if (ret != 0)
{
std::cout << "pthread_attr_setinheritsched() error[" << ret << "]¥n";
}
ret = pthread_attr_setschedpolicy(&attr, SCHED_RR);
if (ret != 0)
{
std::cout << "pthread_attr_setschedpolicy() error[" << ret << "]¥n";
}
pthread_t threads[NUM_OF_THREADS];
for (int i = 0; i < NUM_OF_THREADS; i++)
{
param.sched_priority = i + 1;
ret = pthread_attr_setschedparam(&attr, ¶m);
if (ret != 0)
{
std::cout << "pthread_attr_setschedparam() error[" << ret << "]¥n";
}
ret = pthread_create(&threads[i], &attr, entry, NULL);
if (ret != 0)
{
std::cout << "pthread_create() error[" << ret << "]¥n";
}
}
for (int i = 0; i < NUM_OF_THREADS; i++)
{
pthread_join(threads[i], NULL);
}
pthread_attr_destroy(&attr);
pthread_mutex_destroy(&mtx);
return 0;
}
#2. スレッド生成後に設定する方法
pthread_create()でスレッドを生成したあとで、pthread_setschedparam()関数を使用してスレッドを設定します。
#include <iostream>
#include <pthread.h>
#include <sched.h>
#define NUM_OF_THREADS 4
pthread_mutex_t mtx;
void* entry(void* arg)
{
pthread_mutex_lock(&mtx);
struct sched_param param;
int policy{};
int ret = pthread_getschedparam(pthread_self(), &policy, ¶m);
if (ret != 0)
{
std::cout << "pthread_getschedparam() error[" << ret << "]\n";
}
pthread_mutex_unlock(&mtx);
pthread_mutex_lock(&mtx);
std::cout << "Priority:" << param.sched_priority << " start\n";
pthread_mutex_unlock(&mtx);
// do some work
return NULL;
}
int main()
{
pthread_mutex_init(&mtx, NULL);
pthread_t threads[NUM_OF_THREADS];
struct sched_param param;
pthread_mutex_lock(&mtx);
for (int i = 0; i < NUM_OF_THREADS; i++)
{
ret = pthread_create(&threads[i], &attr, entry, NULL);
if (ret != 0)
{
std::cout << "pthread_create() error[" << ret << "]¥n";
}
}
for (int i = 0; i < NUM_OF_THREADS; i++)
{
param.sched_priority = i + 1;
ret = pthread_setschedparam(threads[i], SCHED_RR, ¶m);
if (ret != 0)
{
std::cout << "pthread_setschedparam() error[" << ret << "]¥n";
}
}
for (int i = 0; i < NUM_OF_THREADS; i++)
{
pthread_join(threads[i], NULL);
}
pthread_mutex_destroy(&mtx);
return 0;
}
本来は、同一CPU上で異なるプライオリティのスレッドを動かしたら、それぞれのスレッドのスループットに差が発生するかという検証をする予定でした。
しかし、CPUアフィニティを設定して同一CPU上で複数スレッドを実行するコードを実行すると、アプリケーションが固まってしまうという問題に遭遇。
このあたりの情報をご存じの方がいらっしゃたら、ぜひ教えていただけると嬉しいです。