C++ 在一个线程中修改成员变量并在另一个线程中读取
我有两个成员变量C++ 在一个线程中修改成员变量并在另一个线程中读取,c++,pthreads,C++,Pthreads,我有两个成员变量 class MessageQueues { .... char* m_InputBuffer; uint32_t m_InputBufferSize; .... }; 我正在当前线程中的函数中更新它们,并使用调试器查看是否更新了成员变量。但在另一个函数中,在单独的线程中运行,成员变量包含垃圾 因此,我有一个函数,它读取两个值并将它们写入两个成员变量,完成后触发另一个线程 ErrorCode MessageQueue::handleIncomin
class MessageQueues {
....
char* m_InputBuffer;
uint32_t m_InputBufferSize;
....
};
我正在当前线程中的函数中更新它们,并使用调试器查看是否更新了成员变量。但在另一个函数中,在单独的线程中运行,成员变量包含垃圾
因此,我有一个函数,它读取两个值并将它们写入两个成员变量,完成后触发另一个线程
ErrorCode MessageQueue::handleIncomingMessage(char receiveBuffer[], const uint32_t bufferSize) {
ES_TRC3("started");
ErrorCode errorCode = ES_SUCCESS;
pthread_mutex_lock(&mutexMsgQueueIncoming);
m_InputBuffer = receiveBuffer;
m_InputBufferSize = bufferSize;
ES_TRC3("triggering and unlocking");
pthread_cond_signal(&msgQueueCondition);
pthread_mutex_unlock(&mutexMsgQueueIncoming);
ES_TRC3("triggered and unlocked");
return errorCode;
}
然后在第二个成员函数中,该函数无限期地在单独的线程中运行并等待消息
ErrorCode MessageQueue::runReceiver(void) {
ES_TRC3("started");
ErrorCode errorCode = ES_SUCCESS;
while(true)
{
ES_TRC3("waiting for input messages");
pthread_cond_wait(&msgQueueCondition, &mutexMsgQueueIncoming);
pthread_mutex_lock(&mutexMsgQueueIncoming);
ES_TRC3("will parse message");
if (strlen(m_InputBuffer) > 0UL) {
if ((errorCode = m_MsgProtocol->parseMessage(m_InputBuffer, m_InputBufferSize)) != ES_SUCCESS)
{
ES_TRC1("failed to parseMessage, error:%d", errorCode);
}
}
ES_TRC3("message parsed");
pthread_mutex_unlock(&mutexMsgQueueIncoming);
}
return errorCode;
}
通过调试器(以及日志消息),我可以看到变量更新和触发的顺序是正确的。所以我不明白为什么在第二个函数中,成员变量似乎不包含正确的值。我在某个地方读到一些关于“挥发性”的东西。但不要真的认为,这是正确的答案。我做错什么了吗
更新:
互斥量在类之外,但在同一个源文件中,在顶部初始化,如下所示
pthread_mutex_t mutexMsgQueueIncoming = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t msgQueueCondition = PTHREAD_COND_INITIALIZER;
事实上,这很奇怪。当我在没有调试器的情况下运行程序时,似乎无法在runReceiver()函数中锁定互斥体。通过调试器,互斥锁被锁定,但成员变量包含垃圾。好的,我想我应该对此进行调查。这里有几个错误:
while
循环处理class MessageQueues {
....
char* m_InputBuffer;
uint32_t m_InputBufferSize;
uint32_t m_WriteGeneration = 0; // <--- a fix.
uint32_t m_ReadGeneration = 0; // <--- a fix.
....
};
ErrorCode MessageQueue::handleIncomingMessage(char receiveBuffer[], const uint32_t bufferSize) {
ES_TRC3("started");
ErrorCode errorCode = ES_SUCCESS;
pthread_mutex_lock(&mutexMsgQueueIncoming);
m_InputBuffer = receiveBuffer;
m_InputBufferSize = bufferSize;
++m_WriteGeneration; // <--- a fix.
ES_TRC3("triggering and unlocking");
pthread_cond_signal(&msgQueueCondition);
pthread_mutex_unlock(&mutexMsgQueueIncoming);
ES_TRC3("triggered and unlocked");
return errorCode;
}
ErrorCode MessageQueue::runReceiver(void) {
ES_TRC3("started");
ErrorCode errorCode = ES_SUCCESS;
while(true)
{
ES_TRC3("waiting for input messages");
pthread_mutex_lock(&mutexMsgQueueIncoming); // <--- a fix.
while(m_ReadGeneration == m_WriteGeneration) // <--- a fix.
pthread_cond_wait(&msgQueueCondition, &mutexMsgQueueIncoming); // <--- a fix.
m_ReadGeneration = m_WriteGeneration; // <--- a fix.
ES_TRC3("will parse message");
if (strlen(m_InputBuffer) > 0UL) {
if ((errorCode = m_MsgProtocol->parseMessage(m_InputBuffer, m_InputBufferSize)) != ES_SUCCESS)
{
ES_TRC1("failed to parseMessage, error:%d", errorCode);
}
}
ES_TRC3("message parsed");
pthread_mutex_unlock(&mutexMsgQueueIncoming);
}
return errorCode;
}
class消息队列{
....
char*m_输入缓冲区;
uint32\u t m\u输入缓冲区大小;
uint32_t m_WriteGeneration=0;//您在第一块代码中锁定在哪里?有解锁,但没有锁定?请提供@JoeyMallone是否有可能在两个线程中mutexmssgqueueincoming不同?可能是某些类副本构造函数具有不同的初始化互斥体?您是否尝试通过ugh它的指针,来自两个线程,而不是通过值传递它?如果在第二个块中有一个虚假的唤醒呢?它是如何重新等待的?@huseyintugrulbuyukisik,好的,让我调查一下。谢谢你的想法/提示。@Joey也许有一天!哎哟,谢谢。我误解了如何使用,pthread_cond__wait()然后。午饭后让我测试一下。可能是错误。我应该更熟悉pthread库。谢谢。p.s。我不能使用C++11。我不能使用Boost。我被困在1998年了P@JoeyMallone1998年你可以使用Boost。哦,我的天哪!哦,那我甚至不在1998年!我不能使用Boost。这不是我的选择。这不是我的选择。@JoeyMallone在pthread原语上制作精简包装器,然后为您执行错误检查。