目次
(1) SCHED_FIFO (先入れ先出しキューイングスケジューリング)
(2) SCHED_RR リアルタイム スケジューリング戦略、タイム スライス ローテーション
(3) SCHED_OTHER 時分割スケジューリング方式 (Linux デフォルト)
2. pthread_attr_setschedpolicy/pthread_attr_getschedpolicy (スレッド スケジューリング ポリシーの取得と設定)
1. pthread_attr_setstacksize/pthread_attr_getstacksize (取得、スレッドスタックサイズ、警告領域サイズの設定)
1. pthread_exit (スレッドは単独で終了します)編集
2. pthread_cancel (スレッドのキャンセル) (スレッドを終了してください)
3. スレッドを作成し、1 秒後にスレッドをキャンセルする要求を送信すると、スレッドが終了します
1. スレッドのスケジューリング
1. 3 つのスケジューリング アルゴリズム
(1) SCHED_FIFO (先入れ先出しキューイングスケジューリング)
静的優先度が 1 から 99 に設定されている場合、スレッドが準備完了状態であれば、静的優先度 0 の通常のスレッドをすぐに横取りできます。
a. 準備ができたら、優先キューの最後に入れます
b. 優先度の高いスレッドにプリエンプトされた後、優先度キューの先頭に配置され、自分より優先度の高いすべてのスレッドが実行されなくなると、実行が再開されます。
c. sched_yield() を呼び出した後、優先キューの最後に配置されます
概要: スレッドは、I/O 要求を送信するか、より優先度の高いスレッドによって横取りされるか、または sched_yield() を呼び出して CPU を積極的に放棄するまで実行されます。
(2) SCHED_RR リアルタイム スケジューリング戦略、タイム スライス ローテーション
SCHED_FIFO と同様に, 違いはタイム スライスが設定されていることです. タイム スライスが使い果たされると,プライオリティ キューの最後に配置されます. sched_rr_get_interval( ) を使用してタイム スライスの特定の値を取得できます.
(3) SCHED_OTHER 時分割スケジューリング方式 (Linux デフォルト)
静的優先度は 0 に設定する必要があります
優先度レベル 0 のこれらのスレッドは、いわゆる動的優先度に従ってスケジュールされます。動的優先度は、スレッドの nice 値から始まります。スレッドが既に準備完了状態にあるが、スケジューラによって無視されるときはいつでも、その動的優先度はCPU をめぐって競合するこれらのスレッドの公平性を確保するために、自動的に 1 単位ずつ増加します。
2. pthread_attr_setschedpolicy/pthread_attr_getschedpolicy (スレッド スケジューリング ポリシーの取得と設定)
2.スレッドスタックが警告領域を閉じます
1. pthread_attr_setstacksize/pthread_attr_getstacksize (取得、スレッドスタックサイズ、警告領域サイズの設定)
2. 各スレッドには比較的独立したスタックがあります
スレッドのスタックがオーバーフローする可能性があり、スタック領域を増やす必要がありますが、警告領域があるため、これを行う必要はありません警告領域は、アクセス権のないメモリであり、スタック領域を保護するために使用されます隣接する 2 つのスレッドが互いに踏みにじられるのを防ぎます。
3.スレッド出口
1. pthread_exit (スレッドは単独で終了します)
2. pthread_cancel (スレッドのキャンセル) (スレッドを終了してください)
特定の瞬間に、スレッドが「自然に死ぬ」のを待つことはできません (たとえば、while(1) で)。スレッドをすぐに終了させる必要があります。スレッドにキャンセル要求を送信して、スレッドを中断させることができます。実行と終了。
また、スレッドがキャンセル要求を受け取ったときの動作は、次の 2 つの要因によって異なります。
1 つは現在のキャンセル状況です。
PTHREAD_CANCEL_ENABLE 有効 (キャンセル可。デフォルト) PTHREAD_CANCEL_DISABLE 無効 (キャンセル不可)
2 番目は、現在のキャンセルの種類です。
遅延応答は、スレッドがキャンセル ポイントに遭遇したときに、キャンセルされた要求にスレッドが応答するのを待ちます。
すぐに対応する
3. スレッドを作成し、1 秒後にスレッドをキャンセルする要求を送信すると、スレッドが終了します
#include <stdio.h>
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
void * func (void * arg)
{
int * p = calloc(1,4);
while(1)
{
printf("这里是func线程,线程ID :%ld \n" , pthread_self() );
sleep(1);
}
*p = 1024 ;
// 退出本线程并设置返回值的地址(返回了num 的地址)
pthread_exit((void *)p); //返回的内存地址应该时一个堆空间
}
int main(int argc, char const *argv[])
{
// 创建线程
pthread_t t_id = -1 ;
pthread_create( &t_id , //新线程ID号
NULL , // 线程属性, NULL 默认属性
func, // 线程需要执行的例程(新线程需要执行的任务《函数》)
NULL ); // 线程的参数
printf("t_id : %ld\n" , t_id) ;
printf("这里是主函数,线程ID :%ld \n" , pthread_self() );
int * retval ;
int ret_val = 0 ;
sleep(1);
pthread_cancel( t_id );
// 阻塞等待接合线程
printf("等待 function 线程退出:\n");
if( ret_val = pthread_join( t_id , (void*)&retval))
{
fprintf(stderr , "接合失败:%s\n" , strerror(ret_val));
}
printf("结合线程成功, 退出值为:%d\n" , *retval);
// 尝试接合线程 (非阻塞)
// int ret_val = 0 ;
// if( ret_val = pthread_tryjoin_np( t_id , (void*)&retval))
// {
// fprintf(stderr , "接合失败:%s\n" , strerror(ret_val));
// }
return 0;
}
上記の例ではスレッドをキャンセルできますが、スレッドの終了値を結合する方法はありません