web-dev-qa-db-ja.com

ブーストを使用したLinuxでのスレッド優先度の設定

Boostライブラリには、スレッドの優先度を設定するためのデバイスがないようです。これはLinuxで使用するのに最適なコードですか、それともより良い方法がありますか?

boost::thread myThread( MyFunction() );

struct sched_param param;
param.sched_priority = 90;
pthread_attr_setschedparam( myThread.native_handle(), SCHED_RR, &param);

Linuxプログラミングの経験はあまりありません。

25
SlickMcRunFast

これが私がそれを行う方法の基本的なテンプレートですが、周りを検索したところ、コード例がほとんどないことがわかったので、それが最善かどうかについての評決が出ていると思います。

問題は、boost :: threadには、スレッドの作成時にpthead属性を渡すことができるコンストラクターがないため、スレッドの開始後に変更を加える必要があることです。それを回避するために私が知っている他の唯一の方法は、プロセス/スレッドスケジュールの継承を介することです。特に指示がない限り、新しいスレッドは作成者のスケジュール/優先度を継承するため、ワーカースレッドを作成する前に現在のスレッドを変更してから、必要に応じて元に戻すことができます。厄介なようですが、それは代替手段です。

これは、うまくいけば両方を実証する例のハックです。必要に応じてポリシーと優先度を変更し、rootとして実行する必要がある場合があります。

優先順位の設定方法に注意してください。さまざまな制限が適用されます。

#include <iostream>
#include <boost/thread/thread.hpp>
#include <unistd.h>
#include <sched.h>
#include <cstdio>


void* threadfunc()
{
    sleep(5);
}

void displayAndChange(boost::thread& daThread)
{
    int retcode;
    int policy;

    pthread_t threadID = (pthread_t) daThread.native_handle();

    struct sched_param param;

    if ((retcode = pthread_getschedparam(threadID, &policy, &param)) != 0)
    {
        errno = retcode;
        perror("pthread_getschedparam");
        exit(EXIT_FAILURE);
    }

    std::cout << "INHERITED: ";
    std::cout << "policy=" << ((policy == SCHED_FIFO)  ? "SCHED_FIFO" :
                               (policy == SCHED_RR)    ? "SCHED_RR" :
                               (policy == SCHED_OTHER) ? "SCHED_OTHER" :
                                                         "???")
              << ", priority=" << param.sched_priority << std::endl;


    policy = SCHED_FIFO;
    param.sched_priority = 4;

    if ((retcode = pthread_setschedparam(threadID, policy, &param)) != 0)
    {
        errno = retcode;
        perror("pthread_setschedparam");
        exit(EXIT_FAILURE);
    }

    std::cout << "  CHANGED: ";
    std::cout << "policy=" << ((policy == SCHED_FIFO)  ? "SCHED_FIFO" :
                               (policy == SCHED_RR)    ? "SCHED_RR" :
                               (policy == SCHED_OTHER) ? "SCHED_OTHER" :
                                                          "???")
              << ", priority=" << param.sched_priority << std::endl;
}


int main(int argc, char* argv[])
{
    int policy, res;

    struct sched_param param;

    if ((policy = sched_getscheduler(getpid())) == -1)
    {
        perror("sched_getscheduler");
        exit(EXIT_FAILURE);
    }

    if ((res = sched_getparam(getpid(), &param)) == -1)
    {
        perror("sched_getparam");
        exit(EXIT_FAILURE);
    }

    std::cout << " ORIGINAL: ";
    std::cout << "policy=" << ((policy == SCHED_FIFO)  ? "SCHED_FIFO" :
                               (policy == SCHED_RR)    ? "SCHED_RR" :
                               (policy == SCHED_OTHER) ? "SCHED_OTHER" :
                                                          "???")
              << ", priority=" << param.sched_priority << std::endl;


    policy = SCHED_RR;
    param.sched_priority = 2;

    if ((res = sched_setscheduler(getpid(), policy, &param)) == -1)
    {
        perror("sched_setscheduler");
        exit(EXIT_FAILURE);
    }

    boost::thread t1(&threadfunc);

    displayAndChange(t1);

    t1.join();

    return 0;
}
24
Duck

このライブラリを見ることができます(私の学生によって書かれ、まだリリースされていません。svnリポジトリを見てください): https://sourceforge.net/projects/threadutility/

基本的に、彼は、プラットフォーム(現在はLinuxまたはWindows)に応じて適切な内部実装を選択することにより、移植可能な方法でスレッドの優先順位を指定および設定できるboost :: threadのラッパーを作成しました。 Linuxでは、コードはsched_setscheduler()システムコールを使用します。

3
knulp

_boost::thread_には、pthread_create()が呼び出される前にpthread属性を取り込む機能があります。タイプ_boost::thread::attributes_を提供し、それ自体はスタックサイズを設定するためにのみ使用できます(それをサポートするシステム上で)が、属性オブジェクトは.get_native_handle()メソッドも提示し、_pthread_attr_t_、ここで必要な属性を設定できます。次に、その_boost::thread::attributes_オブジェクトを引数としてmake_thread()を呼び出すだけです。このセクションの2番目と3番目のコードボックスを参照してください。 http://www.boost.org/doc/libs/1_53_0/doc/html/thread/thread_management.html#thread.thread_management.tutorial.attributes ==

2
tiberious726

Linuxが実際にスレッドの優先順位を持っているとは思いません-ほとんどのカーネルでは「Nice」レベルを使用できますが、それはおそらくそれについてです(スケジューラーを簡素化します)-しかし、すべてのLinuxシステムがそれを尊重するわけではありません! (スケジューラーによって異なります)。

1
Arafangion