Multithreading Windows中多线程的时间消耗是不正常的

Multithreading Windows中多线程的时间消耗是不正常的,multithreading,Multithreading,Windows中多线程的时间消耗是不正常的。我们的设备有5个喷嘴,流程为: 喷嘴同时拾取切屑,所以我使用5个螺纹来完成 将喷嘴移到另一个地方 把筹码放进去 它在正常时间是平滑的,但有时在移动到另一个地方之前会有短暂的停顿(我们可以很明显地看到)。正常情况下,拾取芯片大约需要80毫秒,有时会变为130毫秒。我编写了一个简单的代码来测试它: #include "stdafx.h" #include <WINDOWS.H> #include <PROCESS.H> #inclu

Windows中多线程的时间消耗是不正常的。我们的设备有5个喷嘴,流程为:

  • 喷嘴同时拾取切屑,所以我使用5个螺纹来完成
  • 将喷嘴移到另一个地方
  • 把筹码放进去
  • 它在正常时间是平滑的,但有时在移动到另一个地方之前会有短暂的停顿(我们可以很明显地看到)。正常情况下,拾取芯片大约需要80毫秒,有时会变为130毫秒。我编写了一个简单的代码来测试它:

    #include "stdafx.h"
    #include <WINDOWS.H>
    #include <PROCESS.H>
    #include <iostream>
    #include <Mmsystem.h>
    
    #pragma comment(lib, "winmm.lib")
    
    using namespace std;
    
    static TIMECAPS                 l_timecaps;
    
    UINT WINAPI MainThread(LPVOID lParam /* = NULL */);
    UINT WINAPI TestThread(LPVOID lParam /* = NULL */);
    void MainProcess();
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        //set current process priority as real time
        SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
    
        //use more accurate time
        timeGetDevCaps(&l_timecaps, sizeof(l_timecaps));
        timeBeginPeriod(l_timecaps.wPeriodMin);
    
        UINT uiThreadId = 0;
        HANDLE hEvents = (HANDLE) _beginthreadex(NULL, 0, MainThread, NULL, 0, &uiThreadId);
        SetThreadPriority(hEvents, THREAD_PRIORITY_TIME_CRITICAL);
    
        WaitForSingleObject(hEvents, INFINITE);
    
        cerr << endl << "Press Enter to exit." << endl;
        while (cin.get() != '\n');
    
        timeEndPeriod(l_timecaps.wPeriodMin);
    
        return 0;
    }
    
    UINT WINAPI MainThread(LPVOID lParam /* = NULL */)
    {
        int i = 0;
        while (i < 100)
        {
            MainProcess();
            i++;
        }
    
        return 0;
    }
    
    void MainProcess()
    {
        const int THREAD_NUMBER = 5;
        static HANDLE hEvents[THREAD_NUMBER]; 
        for (int i = 0; i < THREAD_NUMBER; ++i)
            hEvents[i] = NULL;
    
        //log time with more accurate time
        LARGE_INTEGER liPerfFreq={0};
        LARGE_INTEGER liBeginRunTime = {0}; 
        long lBeginRunTime = 0; 
        QueryPerformanceFrequency(&liPerfFreq); 
        QueryPerformanceCounter(&liBeginRunTime);
        lBeginRunTime = liBeginRunTime.QuadPart * 1000 / liPerfFreq.QuadPart;
    
        for (int i = 0; i < THREAD_NUMBER; ++i)
        {
            UINT uiThreadId = 0;
            hEvents[i] = (HANDLE) _beginthreadex(NULL, 0, TestThread, NULL, 0, &uiThreadId);
            SetThreadPriority(hEvents[i], THREAD_PRIORITY_TIME_CRITICAL);
    
            //assign to cpu
            SetThreadAffinityMask(hEvents[i], 0x00000001 + i);
        }
    
        //wait all threads finished
        WaitForMultipleObjects(THREAD_NUMBER, hEvents, TRUE, INFINITE);
    
        LARGE_INTEGER liEndRunTime = {0};
        long lEndRunTime = 0; 
        QueryPerformanceCounter(&liEndRunTime);
        lEndRunTime = liEndRunTime.QuadPart * 1000 / liPerfFreq.QuadPart;
    
        cout << "time: " << lEndRunTime - lBeginRunTime << endl;
    }
    
    
    UINT WINAPI TestThread(LPVOID lParam /* = NULL */)
    {
        //do nothing
        return 0;
    }
    
    #包括“stdafx.h”
    #包括
    #包括
    #包括
    #包括
    #pragma注释(lib,“winmm.lib”)
    使用名称空间std;
    静态时间上限l_时间上限;
    UINT WINAPI主线程(LPVOID lParam/*=NULL*/);
    UINT WINAPI测试线程(LPVOID lParam/*=NULL*/);
    void MainProcess();
    int _tmain(int argc,_TCHAR*argv[]
    {
    //将当前进程优先级设置为实时
    SetPriorityClass(GetCurrentProcess(),实时优先级类);
    //使用更精确的时间
    timeGetDevCaps(&l_timecaps,sizeof(l_timecaps));
    timeBeginPeriod(l_timecaps.wPeriodMin);
    UINT uiThreadId=0;
    HANDLE hEvents=(HANDLE)u beginthreadex(NULL,0,MainThread,NULL,0,&uiThreadId);
    设置线程优先级(事件、线程优先级、时间关键);
    WaitForSingleObject(hEvents,无限);
    
    cerr您的测试线程什么都不做。所有的时间都花在创建和关闭线程上。内核对象管理器和调度程序中的开销将占主导地位。也许一些线程不得不等待其他线程持有(通过API调用)内核锁,从而出现延迟

    当然,这些内部线程可能会在设置优先级的调用完成之前完成:要设置优先级,您确实需要先启动挂起的线程,然后再启动它

    因为你没有测量任何东西,所以你所有的都是间接费用,这将取决于其他情况


    还请记住,虽然您有诸如
    THREAD\u PRIORITY\u TIME\u CRITICAL之类的名称,但Windows不是实时操作系统。

    您在哪个平台上进行此测试?(核心?超线程?)多少个内核?多线程?@Arno有2个内核和4个多线程。你应该查看你的
    SetThreadAffinityMask
    ,掩码最大为
    0x00000001+THREAD\u NUMBER=5-1
    ,你的系统不支持
    cpu
    。始终查看函数返回值。你应该在中得到错误\u无效\u参数这种情况。通过这种方式,5个线程中的两个可能被迫在同一个逻辑cpu上运行。并且:您可能会问自己是否正在处理。是的,您所说的设置它们的优先级是正确的。我们仍然不知道windows中发生了什么,以及如何避免it@JackyZhou见最后一段。几十种变体毫秒数是正常的(调度程序量)。如果您需要在该时间级别上的简洁性,则需要一个适当的RTOS。我很难将项目从windows迁移到RTOS,我不熟悉RTOS,而且项目有点复杂complicated@JackyZhou“RTOS”=“实时操作系统”如果你深入到一个有实时需求的项目中,而没有确保你的平台不能满足这些需求,那么你就会遇到一个没有简单解决方案的问题。