Реализация pthread_cond_wait и pthread_cond_signal, есть побочный эффект? - PullRequest
1 голос
/ 02 декабря 2011

Моя среда в Linux с использованием pthreads, скомпилированных в gcc.

У меня есть 3 потока как потоки сокета, которые получают данные сокета, около 1500 строк в секунду для thread1 и thread2, поток 3 будет получать 400 строк в секунду, в thread1, thread2, thread3 я использую mutex_lock для защиты глобальных переменных, так что thread4 получить эти глобальные переменные будет правильным, конечно, thread4 использовать mutex_lock тоже.

Резьба1:

    Pthread_mutex_lock(&Mutex1);
    iGlobal1 = iGlobal1 + 1;    
    Pthread_mutex_unlock(&Mutex1);

Резьба2:

 Pthread_mutex_lock(&Mutex2);
 iGlobal2 = iGlobal2 + 1;    
 Pthread_mutex_unlock(&Mutex2);

Thread3:

 Pthread_mutex_lock(&Mutex3);
 iGlobal3 = iGlobal3 + 1;    
 Pthread_mutex_unlock(&Mutex3);

Thread4:

while(1)
{
    Pthread_mutex_lock(&Mutex1);
    ilocal1 = iGlobal1;
    Pthread_mutex_unlock(&Mutex1);

    Pthread_mutex_lock(&Mutex2);
    ilocal2 = iGlobal2;
    Pthread_mutex_unlock(&Mutex2);

    Pthread_mutex_lock(&Mutex3);
    ilocal3 = iGlobal3;
    Pthread_mutex_unlock(&Mutex3);

    DoSomething(ilocal1,ilocal2,ilocal3);
}//while 

По моему мнению Thread4 может быть более эффективным, потому что если thread4 выполняется слишком часто, это стоит много процессора, и mutex_lock эффект thread1, thread2 и thread3 ... поэтому я думаю, что использование pthread_cond_signal сделает его лучше, например:

Резьба1:

 Pthread_mutex_lock(&Mutex1);
 iGlobal1 = iGlobal1 + 1 ;    
 pthread_cond_signal(&condxx);
 Pthread_mutex_unlock(&Mutex1);

Резьба2:

 Pthread_mutex_lock(&Mutex2);
 iGlobal2 = iGlobal2 + 1 ;   
 pthread_cond_signal(&condxx);
 Pthread_mutex_unlock(&Mutex2);

Thread3:

 Pthread_mutex_lock(&Mutex3);
 iGlobal3 = iGlobal3 + 1 ;    
 pthread_cond_signal(&condxx);
 Pthread_mutex_unlock(&Mutex3);

Thread4:

while(1)
{

    pthread_cond_wait(&condxx, mutexx);

    Pthread_mutex_lock(&Mutex1);
    ilocal1 = iGlobal1;
    Pthread_mutex_unlock(&Mutex1);

    Pthread_mutex_lock(&Mutex2);
    ilocal2 = iGlobal2;
    Pthread_mutex_unlock(&Mutex2);

    Pthread_mutex_lock(&Mutex3);
    ilocal3 = iGlobal3;
    Pthread_mutex_unlock(&Mutex3);

    DoSomething(ilocal1,ilocal2,ilocal3);
}//while 

Поскольку pthread_cond_signal не ставит в очередь сигнал, поэтому он не причиняет вреда thread1, thread2, thread3 для запуска pthread_cond_signal каждый раз при получении данных сокета, и thread4 будет заблокирован в pthread_cond_wait (& condxx, mutexx) до получения pthread_cond_signal, который сэкономит время процессора, а также не повлияет на thread1, thread2, thread3, потому что используется меньше mutex_lock!

Моя идея в том, чтобы использовать pthread_cond_wait, действующий как usleep, но пока приходят данные, thread4 не пропустит!

Могу я спросить, что у меня есть побочный эффект? Любой совет приветствуется

1 Ответ

3 голосов
/ 04 декабря 2011

Я думаю, ваш подход к созданию потока 4 более эффективен. Если были только поток 1 (производитель) и поток 4 (потребитель), ваш подход является стандартным способом эффективного ожидания потока 4 для того, чтобы данные стали доступны потоку 1. В данном случае складывается присутствие нескольких потоков производителя. (темы 2 и 3).

Страница man для pthread_cond_signal() говорит, что сигнализация состояния, при котором ни один поток не ожидает, не будет иметь никакого эффекта, поэтому в случае, когда потоки 1, 2 и 3 одновременно сигнализируют condxx (как в многопроцессорной системе) ядро будет иметь один из этих вызовов pthread_cond_signal(), чтобы фактически разблокировать поток 4, в то время как два других не будут иметь никакого эффекта.

Другими словами, я думаю, что ваш подход будет работать. И всегда лучше ожидать данных, управляемых ядром (pthread_cond_wait(), select() и т. Д.), Чем опрашивать их в цикле (ваша идея usleep()).

Как говорится, в вашем примере отсутствуют некоторые важные части вашего кода. mutexx должен быть заблокирован перед вызовом pthread_cond_wait(), и он должен быть заблокирован и разблокирован во время вызовов на pthread_cond_signal(). Эта веб-страница содержит пример, очень похожий на ваш вариант использования, и демонстрирует правильные методы блокировки.

...