【发布时间】:2015-08-05 12:08:57
【问题描述】:
我编写了一个 Win32 异步客户端应用程序,我想创建一个线程来分别处理传入的数据。我对以下代码有疑问。线程启动,获取一些数据但没有正常运行(数据不完整)。我看不出问题出在哪里。你能帮帮我吗?
void incData(void *arg) // This is the thread
{
WaitForSingleObject(hIncDataMutex, INFINITE);
char *sRead = _strdup(sReadBuffer.c_str());
appendTextToEdit(hDebug, sRead); // Some data is displayed, but incompletely
string var;
char *pVar = nullptr;
char *next_token = nullptr;
istringstream iss(sReadBuffer); // sReadBuffer is the global variable I use to pass argument to my thread
while (getline(iss, var)) // Default delimiter '\n'
{
pVar = _strdup(var.c_str()); // Cast string to char *
appendTextToEdit(hDebug, pVar);
appendTextToEdit(hDebug, "\n");
if(strstr(pVar, "id=") != NULL)
{
char *label = strtok_s(pVar, "=", &next_token);
char *pId = strtok_s(NULL, "\n", &next_token);
strcpy_s(id, pId);
}
if( strstr(pVar, "version") != NULL)
{
char *label = strtok_s(pVar, "=", &next_token);
char *pVersion = strtok_s(NULL, "\n", &next_token);
strcpy_s(version, pVersion);
}
if( strstr(pVar, "Qh57=") != NULL)
{
char *label = strtok_s(pVar, "=", &next_token);
char *pFoFd = strtok_s(NULL, "\n", &next_token);
strcpy_s(foFd, pFoFd);
}
}
ReleaseMutex(hIncDataMutex);
}
//.....
case FD_CONNECT: // I launch the thread here (I want it to run forever in the background)
{
connectStatus = TRUE;
statusText=TEXT("Connected");
hIncDataMutex = CreateMutex(NULL, false, NULL); // Create incoming data process thread mutex
HANDLE hThread2 = (HANDLE)_beginthread(incData, 0, 0); // Launch incoming data process thread
}
//....
case FD_READ:
{
int bytes_recv = recv(Socket, readBuffer, sizeof(readBuffer), 0);
sReadBuffer = readBuffer; // Copy the buffer to global scope string (used to feed thread)
ReleaseMutex(hIncDataMutex);
}
break;
编辑
这是我的代码,带有新的调试行,以及调试窗口的输出:
void incData(void *arg)
{
WaitForSingleObject(hIncDataMutex, INFINITE);
appendTextToEdit(hDebug, "Inside thread...\n");
string var;
char *pVar = nullptr;
char *next_token = nullptr;
istringstream iss(sReadBuffer); // Put into a stream
while (getline(iss, var)) // Default delimiter '\n'
{
pVar = _strdup(var.c_str()); // Cast string to char *
if(strstr(pVar, "id=") != NULL)
{
char *label = strtok_s(pVar, "=", &next_token);
char *pId = strtok_s(NULL, "\n", &next_token);
strcpy_s(id, pId);
}
if( strstr(pVar, "version") != NULL)
{
char *label = strtok_s(pVar, "=", &next_token);
char *pVersion = strtok_s(NULL, "\n", &next_token);
strcpy_s(version, pVersion);
}
if( strstr(pVar, "Qh57=") != NULL)
{
char *label = strtok_s(pVar, "=", &next_token);
char *pFoFd = strtok_s(NULL, "\n", &next_token);
strcpy_s(foFd, pFoFd);
appendTextToEdit(hDebug, "Qh57=");
appendTextToEdit(hDebug, foFd);
appendTextToEdit(hDebug, "\n");
}
}
ReleaseMutex(hIncDataMutex);
appendTextToEdit(hDebug, "Mutex released by thread\n");
}
//....
case FD_READ:
{
appendTextToEdit(hDebug, "FD_READ event\n");
int bytes_recv = recv(Socket, readBuffer, sizeof(readBuffer), 0);
appendTextToEdit(hDebug, "Bytes reveived\n");
sReadBuffer = readBuffer; // Copy the buffer to string
ReleaseMutex(hIncDataMutex);
appendTextToEdit(hDebug, "End of FD_READ\n");
}
break;
从调试窗口:
FD_CONNECT, begining thread
FD_READ event
Bytes reveived
End of FD_READ
FD_READ event
Bytes reveived
End of FD_READ
Inside thread... // Thread is only called here !
FD_READ event
Bytes reveived
End of FD_READ
Mutex released by thread // Thread ends here
FD_READ event
Bytes reveived
End of FD_READ
等等... 有什么想法吗?
【问题讨论】:
-
字符 0x00 是否出现在
readBuffer的某处?在这种情况下,sReadBuffer = readBuffer;中的string::operator=和char *sRead = _strdup(sReadBuffer.c_str());中的_strdup将仅复制缓冲区的开头直到字符 0x00。 -
不,不,不!您正在到处复制缓冲区,包括进入/退出全局变量。该线程为其整个处理运行持有一个互斥锁。线程不断被创建/终止/销毁。难怪事情进展得很糟糕:(
-
声明一个缓冲区类,可能带有一个向量来保存数据。创建一个实例,(新),加载数据,使用生产者-消费者队列向线程发送实例信号。只启动线程一次,让它在 P-C 队列弹出周围循环,等待缓冲区实例并在它们到达时处理它们。
标签: c++ multithreading winapi client