C+中的线程安全队列+; 这是在C++中实现线程安全队列< /强>的正确方法,它能处理二进制数据的无符号char数组< /强>?
请注意,在中,数据是从主线程生成的,而不是创建的pthread,这使我怀疑pthread_mutex_t是否能够在push和pop上正确工作 线程安全队列C+中的线程安全队列+; 这是在C++中实现线程安全队列< /强>的正确方法,它能处理二进制数据的无符号char数组< /强>?,c++,concurrency,thread-safety,pthreads,queue,C++,Concurrency,Thread Safety,Pthreads,Queue,请注意,在中,数据是从主线程生成的,而不是创建的pthread,这使我怀疑pthread_mutex_t是否能够在push和pop上正确工作 线程安全队列 #include <queue> #include <pthread.h> class ts_queue { private: std::queue<unsigned char*> _queue_; pthread_mutex_t mutex; pthread_cond_t c
#include <queue>
#include <pthread.h>
class ts_queue
{
private:
std::queue<unsigned char*> _queue_;
pthread_mutex_t mutex;
pthread_cond_t cond;
public:
ts_queue()
{
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
}
void push(unsigned char* data)
{
pthread_mutex_lock(&mutex);
_queue_.push(data);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
void pop(unsigned char** popped_data)
{
pthread_mutex_lock(&mutex);
while (_queue_.empty() == true)
{
pthread_cond_wait(&cond, &mutex);
}
*popped_data = _queue_.front();
_queue_.pop();
pthread_mutex_unlock(&mutex);
}
};
您如何知道消费者从未获得数据?当我尝试你的程序时,我得到了一个分段错误,GDB告诉我消费者确实得到了一个指针,但这是一个无效的指针 我相信您的问题在于
\u队列
成员上存在数据竞争push()
调用\u queue\uuu.push(数据)
(写入\u queue\uu
)同时按住push\u mutex
和pop()
调用\u queue\uuu.front()
(读取\u queue\uu
)和\uu queue\uu.pop()
(另一次写入\uu queue\uu
)同时按住pop\ucode>,但按住
和pop()
可以同时发生,导致两个线程同时写入(和读取)\u队列
,这是一种典型的数据竞争
void *consumer_thread(void *arguments)
{
ts_queue *tsq = static_cast<ts_queue*>(arguments);
while (true)
{
unsigned char* data = NULL;
tsq->pop(&data);
if (data != NULL)
{
// Eureka! Received from the other thread!!!
// Delete it so memory keeps free.
// NOTE: In the real scenario for which I need
// this class, the data received are bitmap pixels
// and at this point it would be processed
delete[] data;
}
}
return 0;
}
void main()
{
ts_queue tsq;
// Create the consumer
pthread_t consumer;
pthread_create(&consumer, NULL, consumer_thread, &tsq));
// Start producing
while(true)
{
// Push data.
// Expected behaviour: memory should never run out, as the
// consumer should receive the data and delete it.
// NOTE: test_data in the real purpose scenario for which I
// need this class would hold bitmap pixels, so it's meant to
// hold binary data and not a string
unsigned char* test_data = new unsigned char [8192];
tsq.push(test_data);
}
return 0;
}