LINUX.ORG.RU

Приоритеты потоков... help!


0

0

Я наткнулся на проблему с приоритетами тредов. Возьмем такой код:

#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sched.h>

unsigned int countA;
unsigned int countB;
const unsigned int MAX = 2000000000;

void *startA(void *a) {
    sleep(1);
    
    for(countA = 0; countA < MAX; countA++) {
        if(countA % 1024 == 0)
              printf("Thread A is working, countA = %d\n", countA);
    }

    printf("Thread A has ended: countA = %d, countB = %d\n", countA, countB);
    exit(0);
}


void *startB(void *a) {
    sleep(1);

    for(countB = 0; countB < MAX; countB++) {
        if(countB % 1024 == 0)
              printf("Thread B is working, countB = %d\n", countB);
    }

    printf("Thread B has ended: countA = %d, countB = %d\n", countA, countB);
    exit(0);
}


void check(int r) {
    printf("res = %d\n", r);
    if(r) {
       printf("error = %s\n", strerror(r));
       exit(0);
    }
}

int main() {
    struct sigaction act;
    pthread_t tA, tB;
    pthread_attr_t tA_attr, tB_attr;
    struct sched_param sch;
    int res;
    int MY_SCHED_POLICY = SCHED_FIFO;

    if(geteuid() != 0) {
         fprintf(stderr, "root expected\n");
         return -1;
    }

    MY_SCHED_POLICY = SCHED_FIFO;

    /// tA
    check(pthread_attr_init(&tA_attr));
    check(pthread_attr_setschedpolicy(&tA_attr, MY_SCHED_POLICY));

    /// tB
    check(pthread_attr_init(&tB_attr));
    check(pthread_attr_setschedpolicy(&tB_attr, MY_SCHED_POLICY));

    /// tA
    check(pthread_create(&tA, &tA_attr, &startA, NULL));

    sch.sched_priority = 55;
    check(pthread_setschedparam(tA, MY_SCHED_POLICY, &sch));

    /// tB
    check(pthread_create(&tB, &tB_attr, &startB, NULL));

    sch.sched_priority = 54;
    check(pthread_setschedparam(tB, MY_SCHED_POLICY, &sch));

    //
    sleep(10000000);

    printf("Thread C is exiting: countA = %d, countB = %d\n", countA, countB);
    
    return 0;
}

Тред с меньшим приоритетом вообще не увеличивает свой count. Почему? 
Я читал man sched_setscheduler, там предостерегают использовать 
приотритеты процессов, но подобная ситуация не описывается...

Подскажите, где я неправ.

Да, у меня Red Hat 8, kernel 2.6.20-19.8, LinuxThreads.

Заранее спасибо.

Тут нет ничего удивительного. Используются т.н. RealTime приоритеты (отслеживает их другой планировщик в ядре), в описанном варианте вообще ничего не должно "работать" пока поток A не отсчитает нужное количество циклов, а потом делается выход из программы exit(0). Процесс (все потоки) убивается, поэтому поток B и не стартует.

AVI
()
Ответ на: комментарий от AVI

Я понимаю, что используются RT scheduler. Я не понимаю, почему все-таки поток A работает сколько захочет (очень долго, почти минуту на P4 2.6GHz), не давая потоку B (у которого ведь тоже RT priority) ничего сделать. Неужели у RT процессов такой огромный временной квант?

jek_
() автор топика
Ответ на: комментарий от jek_

Если я правильно помню, то до "размера временного кванта" дело не доходит. У потока A абсолютный приоритет 55 - самый большой из всех потоков в системе. Этот приоритет не меняется ядром ни при каких ситуациях, поэтому (упрощенно) ситуация такая - во главе списка задач на исполнение стоят поток A и поток B, A всегда первый, потому что его приоритет выше. Если поток A уходит из списка (он заблокирован), то работать будет B пока не разблокируется поток A. В этом можно убедиться, если внутри цикла в потоке A поставить небольшой sleep (например usleep(10000)). Пока поток A заблокирован, будет работать поток B. Другой вариант - это выставить обоим потокам одинаковый приоритет, можно будет наблюдать "интересные эффекты", я думаю, что работать они должны будут четко поочереди.

AVI
()
Ответ на: комментарий от AVI

Я думал, что ядро для каждой epoch выделяет всем процессам (ну будем говорить про RT процессы) по кванту. epoch заканчивается, когда все процессы исчерпывают свои кванты. Так что, как мне казалось, все процессы должны успевать сделать хоть что-то...

А как же все на самом деле?

jek_
() автор топика
Ответ на: комментарий от jek_

Мне казалось, что это как-то описано в man'ах на функции, связанных c параметрами scheduler'а (sched_*). Но как я помню, в FIFO режиме планировщик не понижает приоритет и не меняет размер кванта процесса, "выгоняемого" с исполнения. Поэтому этот процесс (поток) оказывается сразу же первым в очереди на исполнение и продолжает выполняться, т.е. он не непрепрывно "сисдит" на процессоре, а постоянно его заново "захватывает".

AVI
()
Ответ на: комментарий от AVI

Да, в теории так. Но тот же самый эффект я наблюдаю и при использовании SCHED_RR, который, как я понимаю, _меняет_ размер кванта и засовывает процесс в хвост очереди...

jek_
() автор топика
Ответ на: комментарий от jek_

При SCHED_RR хитрая ротация идет только среди потоков с одинаковыми абсолютными приоритетами. Если приоритет у потока не максимальный из всех, что стоят в очереди на исполнение, то у него все равно нет шансов:)

AVI
()
Ответ на: комментарий от AVI

Спасибо! Вообщем-то маны я уже читал, но как-то у меня все равно не складывалось понимание. Сейчас уже в общем стало проясняться.

Еще раз спасибо за толковые объяснения :)

jek_
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.