Тупиковая блокировка очереди pthread в C ++ (я думаю)

У меня проблема с pthreads, из-за которой я думаю, что захожу в тупик. Я создал блокирующую очередь, которая, как я думал, работает, но после еще нескольких тестов я обнаружил, что если я попытаюсь отменить несколько потоков, которые блокируются в blocking_queue, у меня возникнет тупик.

Блокирующая очередь будет очень просто и выглядит так:

template <class T> class Blocking_Queue
{
public:
    Blocking_Queue()
    {
        pthread_mutex_init(&_lock, NULL);
        pthread_cond_init(&_cond, NULL);
    }

    ~Blocking_Queue()
    {
        pthread_mutex_destroy(&_lock);
        pthread_cond_destroy(&_cond);
    }

    void put(T t)
    {
        pthread_mutex_lock(&_lock);
        _queue.push(t);
        pthread_cond_signal(&_cond);
        pthread_mutex_unlock(&_lock);
    }

     T pull()
     {
        pthread_mutex_lock(&_lock);
        while(_queue.empty())
        {
            pthread_cond_wait(&_cond, &_lock);
        }

        T t = _queue.front();
        _queue.pop();

        pthread_mutex_unlock(&_lock);

        return t;
     }

priavte:
    std::queue<T> _queue;
    pthread_cond_t _cond;
    pthread_mutex_t _lock;
}

Для тестирования я создал 4 потока, которые используют эту очередь блокировки. Я добавил несколько операторов печати в очередь блокировки, и каждый поток переходит к методу pthread_cond_wait (). Однако, когда я пытаюсь вызвать pthread_cancel () и pthread_join () в каждом потоке, программа просто зависает.

Я также тестировал это только с одним потоком, и он отлично работает.

Согласно документации, pthread_cond_wait () является точкой отмены, поэтому вызов отмены для этих потоков должен привести к остановке их выполнения (а это действительно работает только с 1 потоком). Однако pthread_mutex_lock не является точкой отмены. Может ли что-то происходить в том случае, если при вызове pthread_cancel () отмененный поток получает мьютекс перед завершением и не разблокирует его, а затем, когда следующий поток отменяется, он не может получить мьютекс и взаимоблокировки? Или есть еще что-то, что я делаю неправильно.

Любой совет был бы прекрасен. Спасибо :)

6
задан vimalloc 16 February 2011 в 16:03
поделиться