下面这段代码EchoBackWorker类是一个循环处理socket的子线程,工作的时候会创建出多个实例来处理,SimpleApp是应用逻辑,socket服务器在accpet到客户端请求后会把调用SimpleApp::do_work(),然后do_work会将传递的clientsocket传给全局变量g_client,然后利用event通知EchoBackWorker去处理。现在的问题是,在
g_start_accept = CreateEvent(NULL, FALSE, TRUE, NULL);
设置为TRUE时EchoBackWorker::_loop会莫名其妙的被写成false,造成子线程推出,设置成FALSE后就没有这个问题了。
但是不知道为什么设置成TRUE会造成这个问题,请大家帮忙看看!!!!
HANDLE g_start_search;
HANDLE g_start_accept;
SOCKET g_client;
//////////////////////////////////////////////////////////////////////////
// 功能:转发线程类
//////////////////////////////////////////////////////////////////////////
class EchoBackWorker : public Thread {
add_thread_factory;
bool _loop;
char _recvbuf[DEFAULT_BUFLEN];
public:
unsigned run() {
SOCKET client;
while (_loop)
{
WaitForSingleObject(g_start_search, INFINITE);
client = g_client;
SetEvent(g_start_accept);
int received = recv(client, _recvbuf, DEFAULT_BUFLEN, 0);
_recvbuf[received] = 0;
if (received == SOCKET_ERROR) {
printf("\nrecv error: %d, handle: %d", WSAGetLastError(), _handle);
}
if (SOCKET_ERROR == send(client, _recvbuf, received, 0)) {
printf("\nsend error: %d, handle: %d", WSAGetLastError(), _handle);
}
closesocket(client);
connections++; // 相应连接计数
}
log_warning("worker %d exit, _loop = %d.", _handle, _loop);
return 0;
}
void stop() {
// _loop = false;
WaitForSingleObject(_handle, INFINITE);
}
private:
EchoBackWorker() : _loop(true) {}
~EchoBackWorker(){}
};
const int maxThread = 4;
class SimpleApp : public App {
concurrent::JobManger<SOCKET> _jobMgr;
public:
int init(){
g_start_accept = CreateEvent(NULL, FALSE, TRUE, NULL);
g_start_search = CreateEvent(NULL, FALSE, FALSE, NULL);
// 初始化任务管理器,创建搜索线程
if (_jobMgr.init(maxThread)) // +1: 给转发线程
{
log_error("fail to init job manager.");
return 1;
}
// 创建搜索线程
for (int i = 0; i < maxThread; ++i) {
_jobMgr.add_worker(ThreadFactory::create<EchoBackWorker>());
}
// 创建测试线程
_beginthreadex(NULL, 0, performance, NULL, 0, 0);
return 0;
}
int do_work(SOCKET& client) {
g_client = client;
SetEvent(g_start_search);
WaitForSingleObject(g_start_accept, INFINITE);
return 0;
}
void stop() {
CloseHandle(g_start_accept);
CloseHandle(g_start_search);
}
};