Возврат значений из pthread асинхронно через равные промежутки времени - PullRequest
1 голос
/ 23 июля 2010

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

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;
}

Есть предложения?

Ответы [ 3 ]

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

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

#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;
} 
1 голос
/ 23 июля 2010

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

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