2010-07-23 2 views
1

Функция main() создает поток, который должен жить, пока пользователь не захочет выйти из программы. Поток должен периодически возвращать значения в основные функции. Я попытался сделать что-то подобное, но не работал хорошо -Возвращаемые значения из pthread асинхронно с регулярными интервалами

std::queue<std::string> q; 

void start_thread(int num) 
{ 
std::string str; 
//Do some processing 
q.push(str); 
} 

int main() 
{ 
//Thread initialization 
int i; 
//Start thread 
pthread_create(&m_thread,NULL,start_thread,static_cast<void *>i); 

while(true) 
{ 
    if(q.front()) 
    { 
     std::cout<<q.front(); 
     return 0; 
    } 
} 

//Destroy thread..... 
return 0; 
} 

Любые предложения?

+2

как она не работает хорошо? Не могли бы вы уточнить поведение, которое вы наблюдали? – SirDarius

+0

@SirDarius: так как это демонстрирует несколько разновидностей неопределенного поведения, фактическое поведение может быть сложно описать точно. –

+0

@Mike Seymour: Что-то привело плакат к выводу, что все работает неправильно, и это должно быть объяснено в вопросе. «Не работает» действительно не является достаточным отчетом об ошибках по любому стандарту. В этом случае существует много очевидных недостатков, поэтому мы можем помочь. – Stephen

ответ

3
  • Нельзя читать и писать из контейнеров STL одновременно. Для синхронизации доступа вам понадобится блокировка (см. pthread_mutex_t).
  • Ваша нить подталкивает одно значение в очередь. Кажется, вы ожидаете периодических значений, поэтому вам нужно будет изменить start_thread, чтобы включить цикл, который вызывает queue.push.
  • return 0; в контуре потребителя выйдет main(), когда он найдет значение в очереди. Вы всегда будете читать одно значение и выходить из программы. Вы должны удалить это возвращение.
  • Использование if (q.front()) не является способом проверить, имеет ли ваша очередь значения (фронт предполагает наличие хотя бы одного элемента). Попробуйте if (!q.empty()).
  • Ваша петля while(true) превратит ваш процессор в нечто неприятное. Вы должны посмотреть на condition variables, чтобы ждать значений в очереди в приятной манере.
+3

Помимо этой миссис Линкольн, как вам понравилась игра? –

+1

@David Gelhar: Отступ был непоследовательным. – Stephen

1

попробуйте блокировать мьютексы перед вызовом push()/front() в очереди.

1

Вот рабочий пример того, что это выглядит, как вы пытаетесь достичь:

#include <iostream> 
#include <queue> 
#include <vector> 
#include <semaphore.h> 
#include <pthread.h> 

struct ThreadData 
{ 
    sem_t sem; 
    pthread_mutex_t mut; 
    std::queue<std::string> q; 
}; 

void *start_thread(void *num) 
{ 
    ThreadData *td = reinterpret_cast<ThreadData *>(num); 
    std::vector<std::string> v; 
    std::vector<std::string>::iterator i; 

    // create some data 
    v.push_back("one"); 
    v.push_back("two"); 
    v.push_back("three"); 
    v.push_back("four"); 

    i = v.begin(); 

    // pump strings out until no more data 
    while (i != v.end()) 
    { 
     // lock the resource and put string in the queue 
     pthread_mutex_lock(&td->mut); 
     td->q.push(*i); 
     pthread_mutex_unlock(&td->mut); 

     // signal activity 
     sem_post(&td->sem); 
     sleep(1); 

     ++i; 
    } 

    // signal activity 
    sem_post(&td->sem); 
} 

int main() 
{ 
    bool exitFlag = false; 
    pthread_t m_thread; 
    ThreadData td; 

    // initialize semaphore to empty 
    sem_init(&td.sem, 0, 0); 

    // initialize mutex 
    pthread_mutex_init(&td.mut, NULL); 

    //Start thread 
    if (pthread_create(&m_thread, NULL, start_thread, static_cast<void *>(&td)) != 0) 
    { 
     exitFlag = true; 
    } 

    while (!exitFlag) 
    { 
     if (sem_wait(&td.sem) == 0) 
     { 
      pthread_mutex_lock(&td.mut); 

      if (td.q.empty()) 
      { 
       exitFlag = true; 
      } 
      else 
      { 
       std::cout << td.q.front() << std::endl; 
       td.q.pop(); 
      } 

      pthread_mutex_unlock(&td.mut); 
     } 
     else 
     { 
      // something bad happened 
      exitFlag = true; 
     } 
    } 

    return 0; 
} 
Смежные вопросы