2016-01-22 4 views
1

У меня есть четыре потока, которые ждут переменную условия и переменных пятого потока, когда все четыре потока ждут. Когда я устанавливаю приоритет потока максимум, равный 99, поточный коммутатор занимает много времени, что далеко не приемлемо. Кто-нибудь может взглянуть и рассказать, что происходит?Политика и приоритет Pthread Scheduling

#define N_WORK_THREADS  4 
pthread_mutex_t count_mutex  = PTHREAD_MUTEX_INITIALIZER; 
pthread_cond_t condition_var = PTHREAD_COND_INITIALIZER; 

void *functionCount1(void * arg); 
void *functionCount2(void * arg); 

int count = 0; 
int valid = 0; 
int thread_personal[N_WORK_THREADS]; 

static int display_thread_sched_attr(int id) 
{ 
    int policy, s; 
    struct sched_param param; 

    s = pthread_getschedparam(pthread_self(), &policy, &param); 
    if (s != 0) { printf("pthread_getschedparam"); return 1; } 

    printf("Thread Id=%d policy=%s, priority=%d\n",id, 
      (policy == SCHED_FIFO) ? "SCHED_FIFO" : (policy == SCHED_RR) ? "SCHED_RR" : (policy == SCHED_OTHER) ? "SCHED_OTHER" : "???", 
      param.sched_priority); 

    return 0; 
} 


int main(void) 
{ 
    pthread_t  thread_work[N_WORK_THREADS]; 
    pthread_t  thread; 
    int    i,s; 
    pthread_attr_t attr; 
    struct   sched_param param; 

    s = pthread_attr_init(&attr); 
    if (s != 0) { printf("pthread_attr_init"); return 1; } 

    s = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); 
    if (s != 0) { printf("pthread_attr_setinheritsched"); return 1; } 

    s = pthread_attr_setschedpolicy(&attr, SCHED_RR); 
    if (s != 0) { printf("pthread_attr_setschedpolicy"); return 1; } 

    param.sched_priority = 99; 
    s = pthread_attr_setschedparam(&attr, &param); 
    if (s != 0) { printf("pthread_attr_setschedparam"); return 1; } 

    for (i=0; i<N_WORK_THREADS; i++) { thread_personal[i] = 0; } 

    for (i=0; i<N_WORK_THREADS; i++) { pthread_create(&thread_work[i], &attr, &functionCount1, (void *)i); } 

    param.sched_priority = 99; 
    s = pthread_attr_setschedparam(&attr, &param); 
    if (s != 0) { printf("pthread_attr_setschedparam"); return 1; } 
    pthread_create(&thread, &attr, &functionCount2, (void *)N_WORK_THREADS); 

    for (i=0; i<N_WORK_THREADS; i++) { pthread_join(thread_work[i], NULL); } 
    pthread_join(thread, NULL); 

    for (i=0; i<N_WORK_THREADS; i++) { printf("Thread Id=%d Mutex USed=%d\n",i,thread_personal[i]); } 

    exit(EXIT_SUCCESS); 
} 

void *functionCount1(void * arg) 
{ 
    int i; 
    int id = (int) arg; 

    display_thread_sched_attr(id); 

    for(i=0; i<10; i++) 
    { 
    pthread_mutex_lock(&count_mutex); 

    thread_personal[id] += 1; 

    while (((count>>id) & 0x1) == 0) 
    { 
     pthread_cond_wait(&condition_var, &count_mutex); 
    } 
    count = count^ (1<<id); 

    printf("Thread Id %d: Valid = %d\n",id,valid); 

    pthread_mutex_unlock(&count_mutex); 
    } 

    return NULL; 
} 

void *functionCount2(void * arg) 
{ 
    int check; 
    int id = (int) arg; 

    display_thread_sched_attr(id); 

    check =0; 
    while (check < 10) 
    {  
    pthread_mutex_lock(&count_mutex); 

    if (count == 0) 
    { 
     pthread_cond_broadcast (&condition_var); 
     count =0xF; 
     printf("Thread Id %d: Counter = %d\n",id,check); 
     valid = check++; 
    } 

    pthread_mutex_unlock(&count_mutex); 
    } 
    return NULL; 
} 
+0

Какая платформа и инструменты вы используете? Программа вообще не работает для меня (потоки не печатают вывод), если я не закомментирую весь код конфигурации политики планирования. Я тестирую Linux 3.16.0 x86_64 с версией gcc версии 4.8.4. –

+0

Linux 3.14, gcc 4.8.3 на платформе armv7. – user3257306

ответ

1

Я не могу проверить свою программу с кодом политики планирования позволила, потому что программа просто не работает, когда это там (как я упоминаю в комментарии: Linux 3.16.0 x86_64 с GCC 4.8. 4).

Но я предполагаю, что ваша проблема может быть из-за петли в functionCount2():

while (check < 10) 
{  
    pthread_mutex_lock(&count_mutex); 

    if (count == 0) 
    { 
     pthread_cond_broadcast (&condition_var); 
     count =0xF; 
     printf("Thread Id %d: Counter = %d\n",id,check); 
     valid = check++; 
    } 

    pthread_mutex_unlock(&count_mutex); 
} 

В целом, приобретение объектов мьютекса в Pthreads не гарантируется, чтобы быть справедливым или FIFO (хотя, если честно , Я не уверен, как политики планирования потоков могут повлиять на него). Я считаю, что этот цикл освобождает count_mutex, а затем сразу же его повторно приобретает, хотя другие потоки заблокированы, ожидая, чтобы требовать мьютекс. И с помощью политики планирования это может произойти до тех пор, пока поток не использует свой квант.

+0

Я подозреваю то же самое, что любой поток использует свой квант, но вы указываете на функциюCount2()? Почему это невозможно в функции functionCount1()? И ваша точка правильная, поскольку я считал мьютексы, полученные функциейCount2(), и количество приходит в тысячах ... – user3257306

+0

Теперь я получил вашу пинту, и вы были абсолютно правы. ФункцияCount2() снова и снова приобретала мьютекс, что вызывало проблему. Я добавил немного сна перед запросом блокировки мьютекса, и проблема уходит. Спасибо тонну .... Можете ли вы предложить, каков эффект планирования политики и приоритета по этой проблеме? Поскольку я заметил другое поведение, когда я изменил приоритет потока, который использует functionCount2(). – user3257306

+0

Извините, я не могу сказать много о политике планирования - у меня просто не было возможности использовать ее. Все, что я знаю об этом, - это основы того, что говорят документы. Кроме того, как я заметил, когда я попытался использовать его из вашего примера, все не сработало; У меня не было возможности провести глубокую отладку. –

Смежные вопросы