Windows 7 上的 WinAPI / C++ 中有轻量级信号吗?

问题描述 投票:0回答:1

对于Windows上线程之间的轻量级信号,

WaitOnAddress
是从Windows 8开始的理想工具。我暂时必须支持Windows 7,我发现的最好的改进(包括搜索和阅读MSDN)超过Win32 API 事件与
SleepConditionVariableCS
一起使用。

这是一个最小的示例(在控制台应用程序中处理 Ctrl-C):

//HANDLE Signal;  // event
CONDITION_VARIABLE Signal;
CRITICAL_SECTION cs;

BOOL WINAPI CtrlHandler(DWORD ctl){
  switch (ctl) {
    case CTRL_C_EVENT:  /*SetEvent(Signal);*/ WakeConditionVariable(&Signal); return TRUE;
    default:            return FALSE; // pass it to the system
  }
}

int main(){

  //Signal = CreateEventA(NULL, TRUE /*manual-reset event*/, 
  //                       FALSE/*initial nonsignaled*/, "ctrl-c_sig023xgyI8");
  InitializeConditionVariable(&Signal);  InitializeCriticalSection(&cs);
  
  SetConsoleCtrlHandler(CtrlHandler, TRUE) // register CtrlHandler with the system
  // auto hThread = CreateThread(nullptr, 0, worker, nullptr, ..);
  
  //WaitForSingleObject(Signal, INFINITE);
  EnterCriticalSection(&cs);
    SleepConditionVariableCS (&Signal, &cs, INFINITE);
  LeaveCriticalSection(&cs);
  // stop thread, cleanup, CloseHandle(hThread); CloseHandle(Signal);

  return 0;
}

此示例强制使用“信号”用例:系统启动一个专用线程只是为了运行您的

CtrlHandler
(当用户输入Ctrl-C时),然后它有机会向用户发出信号
main
线程-请求停止。

Win32 API 或 C++ 中是否有更好(更轻量)的方法(当然,C++ 最终必须通过 Win32 API)。

c++ winapi
1个回答
0
投票

看起来没有比

SleepConditionVariableCS/SRW
更快的了。

这些之间没有太大区别。这在我的 CPU 上显示出

SRW
(~2%) 的轻微优势:

int main(int argc, char **argv){

  CONDITION_VARIABLE cv; InitializeConditionVariable(&cv);
  
  //SRWLOCK Signal; InitializeSRWLock(&Signal);
  CRITICAL_SECTION cs; InitializeCriticalSection(&cs);
  //std::mutex mtx;
  //std::condition_variable ccv;

  bool stop_thread = false;
  auto th1 = std::thread([&](){ while(true){ WakeConditionVariable(&cv); if(stop_thread) return; }});
  //auto th1 = std::thread([&](){ while(true){ ccv.notify_one(); if(stop_thread) return; }});

  const int64_t n = 1000 * 1000 * 1000;
  auto start = std::chrono::high_resolution_clock::now();
  for (int64_t i = 0; i < n; i++) {
    //AcquireSRWLockExclusive(&Signal);
    //  SleepConditionVariableSRW(&cv, &Signal, INFINITE, 0);
    //ReleaseSRWLockExclusive(&Signal);
    
    EnterCriticalSection(&cs);
      SleepConditionVariableCS (&cv, &cs, INFINITE);
    LeaveCriticalSection(&cs);
    
    //std::unique_lock lk(mtx);
    //ccv.wait(lk);
  }
  auto elapsed = std::chrono::high_resolution_clock::now() - start;
  stop_thread = true; th1.join();
  double nSec = 1e-6 * std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();
  printf("%.3lf calls/sec\n", n / nSec);
  
  return 0;
}

std::condition_variable
慢了 20%。

底线:如果你不需要递归/你的争用程度较低(没有

Try..
的恶作剧
SRW
),请使用
SRW
(使用 NtCreateKeyedEvent 特殊酱汁),否则使用
CS

© www.soinside.com 2019 - 2024. All rights reserved.