pthreadとSCHED_FIFOによる優先度スケジューリングについて
RTOSのプログラムをLinuxのAPIでシミュレーションできないかと考えています。同じコードをPCでテストすることが目的で、リアルタイム性はあまり気にしてません。
manページ等をみると、スケジューリングポリシーにSCHED_FIFOを指定すると優先度の高いスレッドがブロックされない限り、低優先度のスレッドはブロックされるといった記述がありました。そこで、下記のサンプルコードを試してみましたが期待通りの動作にはなりませんでした。
具体的には、高優先度のスレッドがwhile文で無限ループしているので低優先度のスレッドのprintfが永久に実行されない、というのが期待する動作です。なぜこのサンプルコードではスレッドの切替が行われてしまうのでしょうか?
@user20098さんのコメントを受けて、カーネルバージョン等の追記
Windows10(64bit)上のVirtualBoxでUbuntu16.04(AMD64)をインストールしてテストしています。
$ uname -a
Linux vagrant 4.4.0-87-generic #110-Ubuntu SMP Tue Jul 18 12:55:35 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <assert.h>
static void* prio_high(void* arg)
{
volatile int i = 0;
while (1)
i++;
return NULL;
}
static void* prio_low(void* arg)
{
unsigned int i = 0;
while (1)
{
printf("i = %d\n", i++);
}
return NULL;
}
int main(int argc, char *argv[])
{
struct sched_param param1;
struct sched_param param2;
pthread_attr_t attr1;
pthread_attr_t attr2;
pthread_t th1;
pthread_t th2;
int ret;
ret = pthread_attr_init(&attr1);
assert(ret == 0);
ret = pthread_attr_init(&attr2);
assert(ret == 0);
ret = pthread_attr_setschedpolicy(&attr1, SCHED_FIFO);
assert(ret == 0);
ret = pthread_attr_setschedpolicy(&attr2, SCHED_FIFO);
assert(ret == 0);
param1.sched_priority = 9;
ret = pthread_attr_setschedparam(&attr1, ¶m1);
assert(ret == 0);
param2.sched_priority = 10;
ret = pthread_attr_setschedparam(&attr2, ¶m2);
assert(ret == 0);
ret = pthread_create(&th1, &attr1, prio_low, NULL);
assert(ret == 0);
ret = pthread_create(&th2, &attr2, prio_high, NULL);
assert(ret == 0);
while (1)
sleep(1);
return 0;
}