Multithreading Windows中多线程的时间消耗是不正常的
Windows中多线程的时间消耗是不正常的。我们的设备有5个喷嘴,流程为:Multithreading Windows中多线程的时间消耗是不正常的,multithreading,Multithreading,Windows中多线程的时间消耗是不正常的。我们的设备有5个喷嘴,流程为: 喷嘴同时拾取切屑,所以我使用5个螺纹来完成 将喷嘴移到另一个地方 把筹码放进去 它在正常时间是平滑的,但有时在移动到另一个地方之前会有短暂的停顿(我们可以很明显地看到)。正常情况下,拾取芯片大约需要80毫秒,有时会变为130毫秒。我编写了一个简单的代码来测试它: #include "stdafx.h" #include <WINDOWS.H> #include <PROCESS.H> #inclu
#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”=“实时操作系统”如果你深入到一个有实时需求的项目中,而没有确保你的平台不能满足这些需求,那么你就会遇到一个没有简单解决方案的问题。