queue<int> m_queueThread;//任务列表
//30个线程,300个任务要执行,同时每个线程只能执行一个任务
//全部执行完后等待5秒后全部任务重新开始,直到用户发送命令终止
#include <windows.h>
#include <vector>
#include <queue>using namespace std;
HANDLE hSemaphore;
const int NUM_TASK=300;//总任务数
const int NUM_THREAD=30;//开启线程数n个
const int NUM_WAIT=5*1000;//任务全部结束后隔n秒后,重新开始
static bool b_stop=true;
CRITICAL_SECTION m_cs;
HANDLE hEvent;
static int si_thr;//任务序号/************************
*线程
*
*************************/
unsigned long __stdcall ThreadFunc(void* lpParam)
{
queue<int>* q_Thred=(queue<int>*)lpParam; while(b_stop)
{
EnterCriticalSection(&m_cs);
if(q_Thred->empty())//队列为空,任务全部完成
{
printf("开始等待\n");
printf("正在等待...\n");
DWORD dwWaritRes=WaitForSingleObject(hEvent,NUM_WAIT);
switch(dwWaritRes)
{
case WAIT_OBJECT_0:
printf("遇到事件结束等待\n");
//break;
case WAIT_TIMEOUT:
printf("等待结束!\n");
b_stop=0;
break;
break;
} }
int i_newNum=q_Thred->front();
q_Thred->pop();//取出队列,已完成该任务
LeaveCriticalSection(&m_cs); DWORD dwWaitResult; 
 
dwWaitResult = WaitForSingleObject( 
hSemaphore,   // handle to semaphore
INFINITE);          // zero-second time-out interval switch (dwWaitResult) 

// The semaphore object was signaled.
case WAIT_OBJECT_0: 
printf("%3d:正在执行任务%3d\n",si_thr++,i_newNum);//(*q_Thred).front());
break;  // Semaphore was nonsignaled, so a time-out occurred.
case WAIT_TIMEOUT: 
printf("%3d:TIMEOUT!!!!!!!!!!!!!!!!!!!!",si_thr++);
break; 
}

if (!ReleaseSemaphore( 
hSemaphore,  // handle to semaphore
1,           // increase count by one
NULL) )      // not interested in previous count
{
printf("ReleaseSemaphore error: %d\n", GetLastError());
}
}
return 0;
}
bool Start(void)
{
hSemaphore = CreateSemaphore( 
NULL,   // default security attributes
NUM_THREAD,   // initial count
NUM_THREAD,   // maximum count
NULL);  // unnamed semaphore if (hSemaphore == NULL) 
{
printf("CreateSemaphore error: %d\n", GetLastError());
} //std::vector<int> m_queueThread;//
queue<int> m_queueThread;//任务列表
for(int i=1;i<=NUM_TASK;i++)
{
m_queueThread.push(i);
}
DWORD ThreadID;
for(int i=0;i<NUM_THREAD;i++)
{
HANDLE handle=CreateThread(NULL,
0,
(LPTHREAD_START_ROUTINE)ThreadFunc,
&m_queueThread,
0,
&ThreadID);
SetThreadPriority(handle,THREAD_PRIORITY_IDLE);
}
return true;
}
int main()
{
int nRetCode = 0;
InitializeCriticalSection(&m_cs);
hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
si_thr=0;
if(Start())
printf("结束!\n"); {
// SetEvent(hEvent);
}
//DeleteCriticalSection(&m_cs);
return nRetCode;
}
如题:30个线程,300个任务要执行,同时每个线程只能执行一个任务
全部执行完后等待5秒后全部任务重新开始,直到用户发送命令终止
我这么写有错误,还有什么好的方法?

解决方案 »

  1.   

    M个任务,N个线程,一个线程在同一时间内只能执行一个任务,我是这么做的:
    把任务列表保存到queue里,在线程里一运行一个任务就pop掉这个任务,当queue为空时就结束该线程我写的代码不知为什么只执行几个任务就结束了,M个任务没有执行完
      

  2.   


    看你的代码是这样呀,呵呵,要主线程中加一个
    while(true)
    {
    Sleep(1000);
    }
      

  3.   

    多线程执行“一堆”任务,这个任务堆就是一个全局数据,线程内操作全局数据最重要的是“同步”。
    两种设计方案:
    一,让任务堆放到一个独立的工作线程中(注意不是主线程),各个执行任务的线程中各设一个状态标签,线程每次执行完分配到的一个任务的时候,都先设置一下该状态标签,表明自己准备“进入分配任务等待”状态,然后利用同步对象进入等待中;任务堆所在的那个工作线程的任务就是不断遍历这些线程的状态标签,发现“进入分配任务等待”状态的线程,即分配给它新的任务,然后“激活”它的等待对象...如果任务为空,则不激活,宣告任务全部完成;二,让任务线程自己主动去取任务,把任务堆放在一个全部线程“够”得着的地方,分配任务的方法注意设置同步对象就行了,比如critical section,那实际上是把第一种方案的任务分配操作让给了任务线程本身去执行了。第一种方案要有一个不断循环遍历的线程,感觉有点消耗cpu时钟;第二种有效解决第一种的缺陷,但是线程的职责没第一种划分的清晰了。个人看法,供你参考了。
      

  4.   

    //30个线程,300个任务要执行,同时每个线程只能执行一个任务
    //全部执行完后等待5秒后全部任务重新开始,直到用户发送命令终止
    #include <windows.h>
    #include <assert.h>
    #include <queue>using namespace std;
    HANDLE hSemaphore;
    const int NUM_TASK=333;//总任务数
    const int NUM_THREAD=44;//开启线程数n个
    const int NUM_WAIT=3*1000;//任务全部结束后隔n秒后,重新开始
    CRITICAL_SECTION m_cs;
    HANDLE hEvent;
    int si_thr=1;//任务序号unsigned long __stdcall ThreadFuncMain(void* lpParam);//主线程
    unsigned long __stdcall ThreadFuncChild(void* lpParam);//子线程
    /************************
    *主线程
    *
    *************************/
    unsigned long __stdcall ThreadFuncMain(void* lpParam)
    {
    bool b_Working=true;
    while(b_Working)
    {
    printf("\n开始了!\n");
    InitializeCriticalSection(&m_cs);
    si_thr=1;
    queue<int> m_queueThread;//任务列表
    // m_queueThread.clear();
    assert(m_queueThread.empty()); for(int i=1;i<=NUM_TASK;i++)
    {
    m_queueThread.push(i);
    }
    DWORD ThreadID;
    PHANDLE m_phThreads;
    m_phThreads = new HANDLE[NUM_THREAD];
    for(int i=0;i<NUM_THREAD;i++)
    {
    m_phThreads[i]=CreateThread(NULL,
    0,
    (LPTHREAD_START_ROUTINE)ThreadFuncChild,
    &m_queueThread,
    0,
    &ThreadID);
    SetThreadPriority(m_phThreads[i],THREAD_PRIORITY_IDLE);
    }
    //DWORD dwWr=
    WaitForMultipleObjects(NUM_THREAD,m_phThreads,false,INFINITE);
    //if(dwWr==WAIT_OBJECT_0||dwWr==WAIT_TIMEOUT)//在这里错了,子线程没有全部完成任务??怎么改??
    //{
    printf("任务完成!\n");
    DWORD dwWaritRes=WaitForSingleObject(hEvent,NUM_WAIT);
    switch(dwWaritRes)
    {
    case WAIT_OBJECT_0:
    printf("遇到事件结束等待\n");
    b_Working=false;
    break;
    case WAIT_TIMEOUT:
    printf("等待结束!\n");
    DeleteCriticalSection(&m_cs);
    break;
    //break;
    }
    //} }
    return 0;
    }
    /************************
    *子线程
    *
    *************************/
    unsigned long __stdcall ThreadFuncChild(void* lpParam)
    {
    queue<int>* q_Thred=(queue<int>*)lpParam; while(true)
    {
    EnterCriticalSection(&m_cs);
    if(q_Thred->empty())//队列为空,任务全部完成
    {
    break;
    }
    int i_newNum=q_Thred->front();
    q_Thred->pop();//取出队列,已完成该任务 printf("%3d:正在执行任务%3d\n",si_thr++,i_newNum);//(*q_Thred).front());
    LeaveCriticalSection(&m_cs);
    Sleep(500);
    // printf("%3d:睡眠结束\n",si_thr); }
    return 0;
    }/**********************************
    *开启主线程
    *
    **********************************/
    bool Start(void)
    {
    HANDLE hHandel=CreateThread(NULL,
    0,
    (LPTHREAD_START_ROUTINE)ThreadFuncMain,
    NULL,
    0,
    NULL);
    WaitForSingleObject(hHandel,INFINITE);
    printf("开启主线程!\n");
    return true;
    }
    int main()
    {
    int nRetCode = 0;
    hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
    si_thr=0;
    if(Start())
    printf("结束!\n"); {
    // SetEvent(hEvent);
    }
    return nRetCode;
    }谢谢大家,听了oyljerry的方法,主线程控制30个子线程循环执行300个任务;
    问题解决了,哈哈!
      

  5.   

    还有个问题:用户输入回车键,结束全部任务,这个要怎么做??在main()里写getchar()==多少吗,但是这样在主线程没有退出是不会执行到的
      

  6.   

    //30个线程,300个任务要执行,同时每个线程只能执行一个任务
    //全部执行完后等待5秒后全部任务重新开始,直到用户发送命令终止
    #include <windows.h>
    #include <assert.h>
    #include <queue>
    #include <time.h>using namespace std;
    HANDLE hSemaphore;
    const int NUM_TASK=135;//总任务数
    const int NUM_THREAD=13;//开启线程数n个
    const int NUM_WAIT=3*1000;//任务全部结束后隔n秒后,重新开始
    CRITICAL_SECTION m_cs;
    HANDLE hEvent;
    int si_thr=1;//任务序号
    static int i_thread=1;
    unsigned long __stdcall ThreadFuncMain(void* lpParam);//主线程
    unsigned long __stdcall ThreadFuncChild(void* lpParam);//子线程
    /************************
    *主线程
    *
    *************************/
    unsigned long __stdcall ThreadFuncMain(void* lpParam)
    {
    bool b_Working=true;
    while(b_Working)
    {
    printf("\n开始了!\n");
    si_thr=1;
    queue<int> m_queueThread;//任务列表
    // m_queueThread.clear();
    assert(m_queueThread.empty()); for(int i=1;i<=NUM_TASK;i++)
    {
    m_queueThread.push(i);
    }
    DWORD ThreadID;
    PHANDLE m_phThreads;
    m_phThreads = new HANDLE[NUM_THREAD];
    for(int i=0;i<NUM_THREAD;i++)
    {
    m_phThreads[i]=CreateThread(NULL,
    0,
    (LPTHREAD_START_ROUTINE)ThreadFuncChild,
    &m_queueThread,
    0,
    &ThreadID);
    SetThreadPriority(m_phThreads[i],THREAD_PRIORITY_IDLE);
    //
    }
    DWORD dwWr=WaitForMultipleObjects(NUM_THREAD,m_phThreads,true,INFINITE);
    // if(dwWr==WAIT_OBJECT_0||dwWr==WAIT_TIMEOUT||dwWr==WAIT_FAILED||dwWr==WAIT_ABANDONED_0)//在这里错了,子线程没有全部完成任务??怎么改??
    //{
    printf("任务完成!\n");
    DWORD dwWaritRes=WaitForSingleObject(hEvent,NUM_WAIT);
    switch(dwWaritRes)
    {
    case WAIT_OBJECT_0:
    printf("遇到事件结束等待\n");
    b_Working=false;
    break;
    case WAIT_TIMEOUT:
    printf("等待结束!\n");
    break;
    //break;
    }
    //}
    for(int i;i<NUM_THREAD;i++)
    CloseHandle(m_phThreads[i]); delete []m_phThreads;
    //delete m_queueThread;
    printf("WaitForMultipleObjects任务完成!\n"); }
    return 0;
    }
    /************************
    *子线程
    *
    *************************/
    unsigned long __stdcall ThreadFuncChild(void* lpParam)
    {
    queue<int>* q_Thred=(queue<int>*)lpParam;
    //bool b_Work=true;
    while(true)
    {
    EnterCriticalSection(&m_cs);
    if(q_Thred->empty())//队列为空,任务全部完成//size()==0)//
    {
    LeaveCriticalSection(&m_cs);
    //b_Work=false;
    break;
    }
    int i_newNum=q_Thred->front();
    q_Thred->pop();//取出队列,已完成该任务 printf("%3d:正在执行任务%3d\n",si_thr++,i_newNum);//(*q_Thred).front());
    LeaveCriticalSection(&m_cs);
    srand((unsigned)time(0)); 
    int x=(rand()*si_thr)%500;
    Sleep(x);
    printf("\t\t\t睡眠%d秒后结束\n",x);
    //
    }
    printf("结束一个子线程%d\n",i_thread++);
    return 1;
    }/**********************************
    *开启主线程
    *
    **********************************/
    bool Start(void)
    {
    HANDLE hHandel=CreateThread(NULL,
    0,
    (LPTHREAD_START_ROUTINE)ThreadFuncMain,
    NULL,
    0,
    NULL);
    WaitForSingleObject(hHandel,INFINITE);
    printf("开启主线程!\n");
    return true;
    }
    int main()
    {
    //if(getchar()==(int)"a")
    //{
    // printf("yes");
    // SetEvent(hEvent);
    //} int nRetCode = 0;
    hEvent=CreateEvent(NULL,TRUE,FALSE,NULL);
    si_thr=0;
    InitializeCriticalSection(&m_cs);
    if(Start())
    printf("结束!\n");
    DeleteCriticalSection(&m_cs);
    return nRetCode;
    }现在这个才是对的,原来LeaveCriticalSection(&m_cs);写错地方了
      

  7.   

    你有个地方:for(int i;i<NUM_THREAD;i++)
            CloseHandle(m_phThreads[i]);应该是:
    for(int i=0;i<NUM_THREAD;i++)
            CloseHandle(m_phThreads[i]);
      

  8.   

    大哥大姐我已经没分了,只能在这里碰碰运气了,希望楼主不要怪罪于我,我有个捆饶我好几天的问题:我用函数调用了一个DLL,进入DLL后的界面里添加按钮,点击按钮调用了一个对话框,而当我在这个对话框上用了ADO和DATAGIRD控件后这个对话框就不能显示了,怎么解决? 
    我在EXE操作的时候是可以的,能调用,为什么用DLL就不成功了?
    救救我吧!!!!!!!!!