Linux Cシステムプログラミング(11)スレッド管理スレッド制御

スレッド制御:スレッドの属性の設定は高度な操作であり、この属性はカーネルの動作に影響を与えるため、これらの属性は通常変更されません(特にスレッドカーネルスタックのサイズ)。


1属性構造を作成および破棄する

pthread_create関数を使用してスレッドを作成する場合、2番目のパラメーターattrを介してスレッドの属性を設定し、システムのデフォルト属性を使用してスレッドを作成するためにNULLに設定できます。スレッド属性は構造に編成されます。構造は次のとおりです。

//线程属性结构
typedef struct
{
   int                detachstate;   //线程的分离状态
   int                schedpolicy;   //线程调度策略
   struct sched_param schedparam;    //线程的调度参数
   int                inheritsched;  //线程的继承性
   int                scope;         //线程的作用域
   size_t             guardsize;     //线程栈末尾的警戒缓冲区大小
   int                stackaddr_set;
   void *             stackaddr;     //线程栈的位置
   size_t             stacksize;     //线程栈的大小
}pthread_attr_t;

pthread_attr_initを使用して属性構造を初期化し、pthread_attr_destroy関数を使用して未使用の属性構造を破棄します。関数プロトタイプは次のとおりです。

//pthread_attr_init 函数为属性结构分配内存空间,通过这个参数返回首地址。
int pthread_attr_init (pthread_attr_t *attr);
//pthread_attr_destroy将前者分配的内存空间释放;
int pthread_attr_destroy (pthread_attr_t *attr);
参数attr:一个指向线程属性结构的指针。
函数执行成功返回0,失败返回错误号。

注:2つは一緒に表示される必要があります。そうでない場合、メモリリークが発生します(1つはアドレス割り当てで、もう1つはアドレス解放です)。


2スレッド属性

2.1スレッド分離状態

スレッド分離状況:スレッドがどのように終了するかを判別します。2つの状態があります。

  1. 非分離状態(デフォルト):この時点で、元のスレッドは作成されたスレッドの終了を待ちます。pthread_join()関数が戻る場合のみ、作成されたスレッドは終了し、そのスレッドが占有していたシステムリソースを解放できます。
  2. 分離状態:分離スレッドは他のスレッドによって待機されていない操作が完了すると、スレッドは終了し、システムリソースはすぐに解放されます。

スレッドの分離状態を取得するにはpthread_attr_getdetachstateを使用し、スレッドの分離状態を設定するにはpthread_attr_setdetachstateを使用します。関数プロトタイプは次のとおりです。

int pthread_attr_getdetachstate(const pthread_attr_t *attr,int *detachstate);
int pthread_attr_setdetachstate(pthread_attr_t *attr,intdetachstate);
参数:
Attr   线程属性变量
Detachstate  线程的分离状态属性,有两个值
    PTHREAD_CREATE_DETACHED,以分离状态启动线程;
    PTHREAD_CREATE_JOINABLE,以非分离状态启动线程;
返回值:若成功返回0,若失败返回-1。

使用手順:スレッドの作成時にスレッドの終了状態を知る必要がないことがわかっている場合は、pthread_attr_t構造体のdetachstateスレッド属性を使用して、スレッドを切り離された状態で開始できます。

2.2スタック設定

pthread_createがスレッドを作成するときに、割り当てられたスタックのサイズを指定しない場合、システムはデフォルト値を割り当てます。デフォルト値を表示する方法は次のとおりです。

ulimit -s

スレッドのスタックサイズを取得するにはpthread_attr_getstacksizeを使用し、スレッドのスタックサイズを設定するにはpthread_attr_setstacksizeを使用します。関数プロトタイプは次のとおりです。

int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *stacksize);
参数:
attr            线程属性变量
inheritsched    线程的栈大小,stacksize以字节为单位
返回值:若成功返回0,若失败返回

個人のキャリアスコープに関しては、この設定は主に組み込み環境で行われます。組み込みではメモリがそれほど大きくないため、デフォルト値を使用するとメモリが不足するため、スレッドを作成する前にこのスタックを事前に設定する必要があります。

2.3スケジューリング戦略

スレッドスケジューリングポリシーはAPIを介して設定できます。pthread_attr_getschedpolicyを使用してスケジューリングポリシーを取得し、pthread_attr_setschedpolicyを使用してスケジューリングポリシーを設定します。関数プロトタイプは次のとおりです。

int pthread_attr_getschedpolicy(const pthread_attr_t*attr,int *policy);
int pthread_attr_setschedpolicy(pthread_attr_t *attr,intpolicy);
参数:
attr           线程属性变量
policy         调度策略
	SCHED_FIFO(先进先出),支持优先级1-99
	SCHED_RR(轮转法),支持优先级1-99
	SCHED_OTHER(其它),不支持优先级
返回值:
若成功返回0,若失败返回-1。

SCHED_FIFOおよびSCHED_RR戦略の詳細な説明:

  1. SCHED_FIFO戦略:優先度の高いスレッドが既に実行されているか、それ自体をブロックしていない限り、すぐに実行が開始されます。
  2. SCHED_RR(ラウンドロビン)戦略:タイムスライスを設定します。

注:

  1. SCHED_RRポリシースレッドがブロックせずに一定期間(タイムスライス間隔)より長く実行され、同じ優先度の別のSCHED_RRまたはSCHBD_FIPOポリシースレッドの準備ができている場合、スレッドを準備するために実行中のスレッドがプリエンプトされます。実行できます。
  2. SCHED_FIFOまたはSCHED_RRポリシーを持つスレッドが条件変数を保持または待機し、同じミューテックスをロックすると、それらは優先順位に従って起動されます。つまり、優先度の低いSCHED_FIFOスレッドと優先度の高いSCHED_FIFOスレッドの両方が同じミューテックスロックを待機している場合、ミューテックスがロック解除されると、優先度の高いスレッドが常に最初にブロック解除されます。

2.4スケジューリングパラメータ

スレッドスケジューリングパラメータはAPIを介して設定できます。pthread_attr_getschedparamを使用してスケジューリングパラメータを取得し、pthread_attr_setschedparamを使用してスケジューリングパラメータを設定します。関数プロトタイプは次のとおりです。

int pthread_attr_getschedparam(const pthread_attr_t*attr,struct sched_param *param);
int pthread_attr_setschedparam(pthread_attr_t *attr,conststruct sched_param *param);
参数:
attr           线程属性变量
param          sched_param结构
返回值:若成功返回0,若失败返回-1。

これには、構造sched_pa​​ramが含まれ、次のように実装されます。

struct sched_param
{
    int sched_priority; // 该参数的本质就是优先级
};

構造体sched_pa​​ramのsched_priority子メンバーは、優先度の値を制御します(値が大きいほど優先度が高くなります)。システムでサポートされている優先度の最大値と最小値は、それぞれsched_get_priority_max関数とsched_get_priority_min関数を使用して取得できます。

特記事項:リアルタイムプログラムを作成していない場合は、スレッドの優先度を変更することはお勧めしません。スケジューリング戦略が正しく使用されていないと、プログラムエラーが発生し、デッドロックなどのさまざまな問題が発生します。たとえば、マルチスレッドアプリケーションでは、スレッドに異なる優先度レベルを設定すると、共有リソースが原因で優先度が逆転する可能性があります。

2.5継承

継承は、作成されたプロセスからスケジュールパラメータを継承するか、schedpolicyおよびschedparam属性で明示的に設定されたスケジュール情報を使用するかを決定します。継承情報を取得するにはpthread_attr_getinheritschedを使用し、継承情報を設定するにはpthread_attr_setinheritschedを使用します。対応する関数プロトタイプは次のとおりです。

int pthread_attr_getinheritsched(const pthread_attr_t*attr,int *inheritsched);
int pthread_attr_setinheritsched(pthread_attr_t *attr,intinheritsched);
参数:
attr            线程属性变量
inheritsched    线程的继承性
    PTHREAD_INHERIT_SCHED表示新现成将继承创建线程的调度策略和参数
    PTHREAD_EXPLICIT_SCHED表示使用在schedpolicy和schedparam属性中显式设置的调度策略和参数
返回值:若成功返回0,若失败返回-1。

pthreadはinheritschedのデフォルト値を指定しません。スレッドのスケジューリング戦略とパラメーターが心配な場合は、最初にこの属性を設定する必要があります。


3 pthreadシリーズ関数のクエリメソッド

pthreadシリーズには多くの機能があります。使用した場合、Linuxでmanコマンドを直接使用してクエリを実行することはできませんが、pthreadスレッドのマニュアルページのマニュアルをインストールしてください。インストールコマンドは次のとおりです。

sudo apt-get install manpages-posix-dev

インストールを確認します。

man -k pthread 

pthreadをリストできます。pthreadライブラリの現在のバージョンを表示します。

getconf GNU_LIBPTHREAD_VERSION

スレッドライブラリを使用する場合、gccコンパイルで-lpthread(小文字のL)を追加する必要があります。

元の記事289件を公開 賞賛された47件 30,000回以上の閲覧

おすすめ

転載: blog.csdn.net/vviccc/article/details/105166567