pthreads, как мне узнать, что другой поток внутри процесса не ждет? - PullRequest
8 голосов
/ 30 ноября 2011

ОС - это Linux, работающая с pthreads

У меня есть два рабочих потока, которые работают вечно, пока переменная останова не примет значение true, и потоки не завершатся корректно. Вместо того, чтобы ждать ожидания, оба потока вызывают pthread_cond_wait до тех пор, пока сигнал не уведомит о новой задаче. Система работает хорошо.

Требуется создать поток информации, который будет печатать некоторую отладочную информацию. Информационный поток будет пытаться читать и печатать информацию каждые 30 секунд. Часть этой информации, я хотел бы быть СОСТОЯНИЕМ каждого рабочего потока. Можно ли найти, если поток заблокирован в "pthread_cond_wait"? Если поток ожидает pthread_cond_wait, тогда STATE == ожидает, пока STATE == работает.

 while ( (sharedvaluffer == 0) && (doneflag == 0) ) {
            pthread_cond_wait (&taks_added, &buffer);
        }    

Конечно, мы можем сделать больше кода. Мы можем добавить к приведенному фрагменту глобальную переменную, которая помечает эту ветку как заблокированную Код можно сделать

while ( (sharedvaluffer == 0) && (doneflag == 0) ) {
                lock;
                i_am_waiting = truel
                unlock
                pthread_cond_wait (&taks_added, &buffer);
 } 

Вопрос в том, есть ли более простой и масштабируемый способ. Стек ожидающего потока равен

Thread 6 (Thread 0x40800940 (LWP 20732)):
#0  0x00002ba4567a9326 in pthread_cond_wait@@GLIBC_2.3.2 ()
#1  0x00000000007ce2ed in worker(void*) ()
#2  0x00002ba4567a5193 in start_thread () from /lib64/libpthread.so.0
#3  0x00002ba458a82f0d in clone () from /lib64/libc.so.6

Ответы [ 4 ]

1 голос
/ 30 ноября 2011

Я бы пошел простым путем и включил бы перечисление состояний для каждого потока. Перед каждым изменением концептуального состояния вы должны изменять его.

void worker(void* parm)
{
    threadstate_t *state = (threadstate_t*)parm;

    /* ... */
    while (...) {
         state->current = STATE_WORKING;

         /* ... */

         state->current = STATE_WAITING;
         /* res = pthread_cond_wait(cond, mutex); */
    }
}

Тогда в вашей ветке допроса:

void worker_dbg(void* parm)
{
    threadstate_t *states = (threadstate_t*)parm;
    int i;

    while (run) {
        for (i = 0; i < NWORKERS; ++i) {
            /* _state is a map of states to strings */
            printf("Thread %d: %s\n", states[i].id, _state[states[i].current]);
        }
        sleep(30);
    }
}

Если вы на выключены на 30 секунд из-за того, что состояние обновилось вправо после печати, это не имеет значения. Нет необходимости блокировать состояние, так как вы пишете только от владельца, а читаете только из потока отладки.

1 голос
/ 30 ноября 2011

Вы можете зарегистрировать общую структуру s в мьютексе с помощью pthread_mutexattr_getpshared , где каждый поток регистрирует свое состояние (работает, не работает) с помощью pthread_self().

Перед проверкой переменной условия вы можете установить s[pthread_self()]->state = WAITING, а после проверки вы можете установить s[pthread_self()]->state = WORKING.

Обязательно спроектируйте структуру, чтобы не возникало условий гонки.

0 голосов
/ 30 ноября 2011

Вы можете использовать возврат pthread_self() в качестве идентификатора для владения мьютексом. Храните и сравнивайте. Поскольку мьютекс может быть получен одним потоком одновременно, вы будете знать, какой поток работает (не ожидает), а какой нет.

0 голосов
/ 30 ноября 2011

Предположительно, вы используете мьютекс, который блокируется при уведомлении о состоянии; если это так, в вашем информационном потоке просто попробуйте заблокировать этот мьютекс - если вы его получите, вполне возможно, что во время выборки поток будет ожидание, иначе, если он заблокирует, то вы знаете, что поток делает свое дело (т.е. он получил этот мьютекс, что означает, что он находится в критической секции)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...