2012-02-16 14 views
5

LinuxシステムではSCHED_FIFOまたはSCHED_RRポリシーをrootにしてスレッドを生成しようとしていますが、pthread_create()の呼び出しは1(EPERM)を返します。 pthread_create()のマニュアルページに、EPERMは "呼び出し側が必要なスケジューリングパラメータまたはスケジューリングポリシーを設定するための適切な権限を持っていないことを示しています。 SCHED_FIFOまたはSCHED_RRを指定できないようにする必要がありますか?LinuxでSCHED_FIFOスレッドのpthread_create()をrootとして呼び出すとき

スレッドを作成するコードは、それだけの小さなプログラムに取り除いています。それは私にはうまく見えますが、まだエラーが発生します。私は間違って何をしていますか?

プログラム:

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 

static void *_Thread(void *arg) 
{ 
    (void)arg; 
    printf("Thread running!\n"); 
    return NULL; 
} 

int main(void) 
{ 
    int retVal; 
    pthread_attr_t attr; 
    struct sched_param schedParam; 
    pthread_t thread; 

    retVal = pthread_attr_init(&attr); 
    if (retVal) 
    { 
     fprintf(stderr, "pthread_attr_init error %d\n", retVal); 
     exit(1); 
    } 

    retVal = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); 
    if (retVal) 
    { 
     fprintf(stderr, "pthread_attr_setinheritsched error %d\n", retVal); 
     exit(1); 
    } 

    retVal = pthread_attr_setschedpolicy(&attr, SCHED_FIFO); 
    if (retVal) 
    { 
     fprintf(stderr, "pthread_attr_setschedpolicy error %d\n", retVal); 
     exit(1); 
    } 

    schedParam.sched_priority = 1; 
    retVal = pthread_attr_setschedparam(&attr, &schedParam); 
    if (retVal) 
    { 
     fprintf(stderr, "pthread_attr_setschedparam error %d\n", retVal); 
     exit(1); 
    } 

    retVal = pthread_create(&thread, 
          &attr, 
          _Thread, 
          NULL); 
    if (retVal) 
    { 
     fprintf(stderr, "pthread_create error %d\n", retVal); 
     exit(1); 
    } 

    retVal = pthread_join(thread, NULL); 
    if (retVal) 
    { 
     fprintf(stderr, "pthread_join error %d\n", retVal); 
     exit(1); 
    } 

    printf("main run successfully\n"); 
    return 0; 
} 

このプログラムはroot権限でコンパイルして実行されています。実行すると、プログラムはpthread_createの呼び出しで失敗し、EPERMを返します。

スレッドをSCHED_RRスケジューリングに変更しても、EPERMはまだpthread_createから返されます。

スケジューリングをSCHED_OTHERスケジューリングに変更し、優先度を0に変更すると、プログラムをエラーなく実行できます。

+0

私はあなたが '呼び出し元のユーザーに設定CAP_SYS_NICE'能力が必要と考えています。私はこれが 'sudo'とどのように機能するかについてはあまりよく分かりません。' man 7 capabilities'をチェックしてください。 –

+0

リアルタイム優先度制限を設定するのと同じ方法で 'ulimit -e'を使ってniceレベルを設定できるようです。それは私に "ユーレカ"を提供していない!瞬間、まだ。 – ChrisL

+0

私たちが仕事場で使っているLinuxシステムは、仮想化されたサーバーです。私はここでストローを握っていますが、それはリアルタイムの優先順位を設定することに影響を与える可能性がありますか? – ChrisL

答えて

4

リアルタイム優先度のソフト制限があまりにも厳しくなければなりません。

コードを実行する前にシェルのulimit -r unlimitedを呼び出してください。またはコードにsetrlimit(RLIMIT_RTPRIO, ...)と直接電話してください。

システム全体の制限は/etc/security/limits.confに設定されています。

+0

'ulimit -r'を呼び出すと、実際にはルートのリアルタイム優先度の上限が0であることが分かりました。まず' ulimit -r unlimited'を使って変更してから、 'setr​​limit(...) 'を使ってプログラムを変更しました。限界が変わったことを確認してください、私はまだEPERMを持っています。 – ChrisL

+0

ARMのような特別な環境にいますか? uname -aとは何ですか? –

+0

'uname -a'は私に' Linux cumanta 2.6.32-042stab044.17#1 SMP Fri Jan 13 12:53:58 MSK 2012 i686 i686 i386 GNU/Linux'を与えます。マシンはCentOS 6.2を実行します。 – ChrisL

1

Linux(2.6カーネル)、Solaris 9 &でコードをテストしました。問題ありません。あなたのリアルタイム優先度設定と関係しています。あなたはそれを変更することができます:

ulimit -r unlimited 

oops。マキシムはすでに答えを得ています....

0

rootユーザーとしてプログラムを実行してください。なぜならスケジューリング(FIFOとRRのためのスケジューリング)が面倒だからです。相対的な優先順位を付けて(含意によって)また、rootだけが行うことができます。

通常、上記のプログラムを実行すると、pthread_creare()はEPERMを返しますが、rootユーザーは問題なく動作します。詳細情報をご覧ください

http://www.linuxforums.org/forum/programming-scripting/111359-pthread-error.html

関連する問題