V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
tommark
V2EX  ›  程序员

求助一个关于 socket,多线程的问题!!!

  •  1
     
  •   tommark · 2014-12-05 20:33:43 +08:00 · 2612 次点击
    这是一个创建于 3422 天前的主题,其中的信息可能已经有所发展或是发生改变。
    下面这段代码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);
    }
    };
    2 条回复    2014-12-06 16:08:12 +08:00
    X140Yu
        1
    X140Yu  
       2014-12-06 15:59:10 +08:00
    CreateEvent的第几个参数?
    tommark
        2
    tommark  
    OP
       2014-12-06 16:08:12 +08:00
    @X140Yu 第三个参数
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   1098 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 18:48 · PVG 02:48 · LAX 11:48 · JFK 14:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.