10. オペレーティング システム - 関連するスレッドの属性 (2)

目次

1. スレッドのスケジューリング

1. 3 つのスケジューリング アルゴリズム

(1) SCHED_FIFO (先入れ先出しキューイングスケジューリング)

(2) SCHED_RR リアルタイム スケジューリング戦略、タイム スライス ローテーション

(3) SCHED_OTHER 時分割スケジューリング方式 (Linux デフォルト)

 2. pthread_attr_setschedpolicy/pthread_attr_getschedpolicy (スレッド スケジューリング ポリシーの取得と設定)

 2.スレッドスタックが警告領域を閉じます

1. pthread_attr_setstacksize/pthread_attr_getstacksize (取得、スレッドスタックサイズ、警告領域サイズの設定)

 2. 各スレッドには比較的独立したスタックがあります

3.スレッド出口

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;
}

上記の例ではスレッドをキャンセルできますが、スレッドの終了値を結合する方法はありません

おすすめ

転載: blog.csdn.net/weixin_45981798/article/details/129813932