Выберите поведение - PullRequest
1 голос
/ 14 июля 2010

Возможно, это простой вопрос, но я не смог найти четкого ответа на него. У меня есть несколько потоков в коде c, и один из них использует select, чтобы ждать n секунд. Вопрос, который у меня есть, заключается в том, блокирует ли он весь процесс на n секунд (например, usleep) или выбирает блокировку только вызывающего потока (больше похоже на nanosleep). Спасибо за ответы.

Ответы [ 3 ]

4 голосов
/ 14 июля 2010

Я видел несколько реализаций, в которых один поток блокируется на select, в то время как другие потоки продолжают обработку - поэтому, да, он только блокирует работающий поток.

(извините за отсутствие ссылок)

1 голос
/ 14 июля 2010

Да. Неаккуратный, но все же довольно убедительный тест.

#include <iostream>
#include <pthread.h>
#include <sys/time.h>

using namespace std;

pthread_mutex_t cout_mutex = PTHREAD_MUTEX_INITIALIZER;

void *task1(void *X)
{
   timeval t = {0, 100000};

    for (int i = 0; i < 10; ++i)
    {
        pthread_mutex_lock(&cout_mutex);
        cout << "Thread A going to sleep" << endl;
        pthread_mutex_unlock(&cout_mutex);

        select(0, NULL, NULL, NULL, &t);

        pthread_mutex_lock(&cout_mutex);
        cout << "Thread A awake" << endl;
        pthread_mutex_unlock(&cout_mutex);
    }

   return (NULL);
}


void *task2(void *X)
{
   pthread_mutex_lock(&cout_mutex);
   cout << "Thread B down for the long sleep" << endl;
   pthread_mutex_unlock(&cout_mutex);

   timeval t = {5, 0};
   select(0, NULL, NULL, NULL, &t);

   pthread_mutex_lock(&cout_mutex);
   cout << "Thread B glad to be awake" << endl;
   pthread_mutex_unlock(&cout_mutex);

   return (NULL);
}


int main(int argc, char *argv[])
{
  pthread_t ThreadA,ThreadB;

  pthread_create(&ThreadA,NULL,task1,NULL);
  pthread_create(&ThreadB,NULL,task2,NULL);

  pthread_join(ThreadA,NULL);
  pthread_join(ThreadB,NULL);

  return (0);
}  
1 голос
/ 14 июля 2010

Спецификация POSIX для select специально упоминает "нить" только в одном месте, где говорится о восстановлении маски сигнала вызывающего потока с помощью pselect().

Как и в случае с другими ответами, мой опыт также говорит, что ответ - да, он блокирует только вызывающий поток.

...