首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • 定时启动N个线程,10分钟内若N个线程都已结束,则重新启动这N个线程,如何实现? [已结贴,结贴人:ezdevelop]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ezdevelop
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 揭帖率:
    发表于:2007-11-15 16:00:25 楼主
    每天早上1点定时启动N个线程(0 <N <10),线程里处理一些SOCKET R/W。

    1) 线程函数
    thread_request()
    {
        while(1) {
            SOCKET R/W;
            消息循环
        }
        // 退出条件是收到主界面的WM_THREAD_CANCEL消息或SOCKET ERROR。
    }

    2) 开启线程
    thread_start()
    {
    std::vector <HANDLE> m_hThreads;
    std::vector <CTestThread *> m_vecThreads; // 用于向线程发送WM_THREAD_CANCEL消息

    ....

    CTestThread *pThread;
    for (i=0; i <N; i++) {
    pThread = (CCnnicThread*)AfxBeginThread(RUNTIME_CLASS(CTestThread), THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
    pThread->m_pMainWnd = this;
    pThread->something = something;
    pThread->PostThreadMessage(WM_THREAD_START, 0, 0);
    pThread->ResumeThread();
    m_vecThreads.push_back(pThread);
    }
    }

    3) OnTimer
    若时间==1点&&m_bIsRunning==FALSE,则启动thread_start,并标记m_bIsRunning=TRUE;
    若时间>1点&&时间 <=1点10分&&m_bIsRunning==FALSE,则再次启动thread_start,并标记m_bIsRunning=TRUE;

    现在的问题是,我如何在这N个线程都结束后设置m_bIsRunning=FALSE,以便我在1点至1点10分之间再次启动thread_start,因为线程里可能会在这10分钟之前服务器端没开启导致SOCKET ERROR直接退出。
    100  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ezdevelop
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2007-11-15 16:07:231楼 得分:0
    我需要在1点10分之后,线程里能够正常进行SOCKET R/W,除非收到WM_THREAD_CANCEL消息。

    所以需要在1点至1点10分之间判断,若创建的所有线程已退出,则重新开启这些线程。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • chehw
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2007-11-15 16:11:552楼 得分:30
    定义一个数据HANDLE hThreads[N];
    创建线程时将每个句柄保存至hTreads[i];

    在OnTimer中
    WaitForMultipleObjects(n, hThreads, TRUE, INFINITE);
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • stivenjia
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2007-11-15 16:18:023楼 得分:10
    1.启动线程记录GetSystemTime()->转换为秒单位,记录超时时间为SYSTEMTIME.wMinute+10转换为秒单位
    2.在定时器GetSystemTime->转为秒单位>=为SYSTEMTIME 则为超时那么就重新启动线程。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ezdevelop
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2007-11-15 16:30:014楼 得分:0
    To chehw:

    我想过这种方法,但是在OnTimer中调用WaitForMultipleObjects不是阻塞了吗?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • chehw
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2007-11-15 17:20:495楼 得分:20
    别放在WM_TIMER中, 另开一个线程,
    LRESULT WaitThread(LPVOID pv)
    {
      while(TRUE)
      {
        WaitForMultipleObjects(n,  hThreads,  TRUE,  INFINITE);
        RestartThreads();
      }
      return 0L;
    }

    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ezdevelop
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2007-11-15 17:57:266楼 得分:0
    偶想了另一种方法

    1) 在thread_start里记录线程ID
    m_vecThreadIDs.push_back(pThread->m_nThreadID);

    2) 在thread_request退出的时候发送WM_THREAD_FINISHED消息,并把m_nThreadID传回。

    3) 新加一个thread_finished函数用于处理WM_THREAD_FINISHED的消息
    m_vecThreadIDs.erase(传回的线程ID)

    4) 然后再OnTimer事件里判断是否m_vecThreadIDs为空来确定线程是否执行结束

    不知道此方法是否有缺陷
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • msn123321
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2007-11-15 18:11:217楼 得分:10
    我认为楼上的思路可以啊,我感觉就是如果线程被异常终止,那可能就不会发WM_THREAD_FINISHED消息了,可能要注意这个处理,我比较倾向于用chehw的方法,思路很清晰
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • daidongsheng
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2007-11-15 20:38:268楼 得分:10
    启动N个线程的时候记录时间

    按chehw 的说法:

    定义一个数据HANDLE  hThreads[N];
    创建线程时将每个句柄保存至hTreads[i];

    WaitForMultipleObjects(n,  hThreads,  TRUE,  INFINITE);

    等上面函数结束 取当前时间,计算时间差判断是不是小于十分钟
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • WingForce
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2007-11-15 22:15:399楼 得分:10
    恩,如果用等待线程
    不再用一个内核定时器,把这个内核定时器句柄和10个线程的句柄都传给WaitForMultipleObjects
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • ezdevelop
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2007-11-16 09:54:0110楼 得分:0
    线程个数N是个不定数时该怎么传递呢?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • jameshooo
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    • 2

      4

    发表于:2007-11-16 10:31:2711楼 得分:10
    WaitForMultipleObjects(n, hThreads, TRUE, 1); 这样就不会阻塞
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • WingForce
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2007-11-16 13:59:0212楼 得分:0
    线程个数N是个不定数时该怎么传递呢?
    ================================================
    其实,在WM_TIMER中不一定需要使用等待线程去wait
    可以用GetExitCodeThread获取各个线程的退出码,如果存在STILL_ACTIVE,就说明还有线程没有结束
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • zhstars
    • 等级:
    • 可用分等级:
    • 总技术专家分:
    • 总技术专家分排名:
    发表于:2008-07-06 07:31:3213楼 得分:0
    学学习!
    修改 删除 举报 引用 回复

    网站简介广告服务网站地图帮助联系方式诚聘英才English 问题报告
    北京创新乐知广告有限公司 版权所有 京 ICP 证 070598 号
    世纪乐知(北京)网络技术有限公司 提供技术支持
    Copyright © 2000-2008, CSDN.NET, All Rights Reserved