Advertisement

c++ 知识点 : 线程相关

阅读量:

1、线程开始事件、线程结束事件、WaitForMultipleObjects 控制线程

假如线程是无限循环的,需要从线程外部控制线程结束

复制代码
  //用于线程管理的两事件

    
 	//HANDLE CreateEventA(
    
 	//	LPSECURITY_ATTRIBUTES lpEventAttributes,
    
 	//	BOOL                  bManualReset,
    
 	//	BOOL                  bInitialState,
    
 	//	LPCSTR                lpName
    
 	//	);
    
 	// create a "loopback capture has started" event
    
 	HANDLE hStartedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    
 	if (NULL == hStartedEvent) {
    
 		printf("CreateEvent failed: last error is %u\n", GetLastError());
    
 		return -__LINE__;
    
 	}
    
  
    
 	// create a "stop capturing now" event
    
 	HANDLE hStopEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    
 	if (NULL == hStopEvent) {
    
 		printf("CreateEvent failed: last error is %u\n", GetLastError());
    
 		CloseHandle(hStartedEvent);
    
 		return -__LINE__;
    
 	}
    
    
    
    
    AI助手

创建线程

将事件作为参数传入线程

复制代码
  // create arguments for loopback capture thread

    
 	LoopbackCaptureThreadFunctionArguments threadArgs;
    
 	threadArgs.hr = E_UNEXPECTED; // thread will overwrite this
    
 	threadArgs.pMMDevice = prefs.m_pMMDevice;
    
 	threadArgs.bInt16 = prefs.m_bInt16;
    
 	threadArgs.hStartedEvent = hStartedEvent;  //将这两个事件作为参数,传入线程
    
 	threadArgs.hStopEvent = hStopEvent;        //
    
 	threadArgs.nFrames = 0;
    
 	threadArgs.bMono = prefs.m_bMono;
    
 	threadArgs.iSampleRateDivisor = prefs.m_iSampleRateDivisor;
    
    
    
    
    AI助手
复制代码
  //创建线程

    
 	HANDLE hThread = CreateThread(
    
 		NULL, 0,
    
 		LoopbackCaptureThreadFunction, &threadArgs,
    
 		0, NULL
    
 		);
    
 	if (NULL == hThread) {
    
 		printf("CreateThread failed: last error is %u\n", GetLastError());
    
 		CloseHandle(hStopEvent);
    
 		CloseHandle(hStartedEvent);
    
 		return -__LINE__;
    
 	}
    
    
    
    
    AI助手

线程内部处理:预处理过程、无限循环过程

复制代码
    hr = pAudioClient->Start();

    
     if (FAILED(hr)) {
    
     printf("IAudioClient::Start failed: hr = 0x%08x\n", hr);
    
     AvRevertMmThreadCharacteristics(hTask);
    
     pAudioCaptureClient->Release();
    
     CloseHandle(hWakeUp);
    
     pAudioClient->Release();
    
     return hr;
    
     }
    
 	//预处理结束,通知主线程,此时主线程使用WaitForMultipleObjects 等待
    
     SetEvent(hStartedEvent);
    
     
    
     // loopback capture loop
    
     HANDLE waitArray[2] = { hStopEvent, hWakeUp };
    
     DWORD dwWaitResult;
    
  
    
 	//循环阶段
    
     bool bDone = false;
    
     for (UINT32 nPasses = 0; !bDone; nPasses++) 
    
    
    
    
    AI助手

主线程序依赖于调用该函数来分析出当前状态

复制代码
 DWORD WaitForMultipleObjects(

    
   DWORD nCount,            // 句柄的数量 最大值为MAXIMUM_WAIT_OBJECTS(64)
    
   CONST HANDLE* lpHandles, //句柄数组的指针
    
   BOOL fWaitAll,           //等待所有事件有信号,还是只要一个有信号就返回
    
   DWORD dwMilliseconds     //超时时间 超时后向执行。 如果为INFINITE 永不超时。如果没有信号量就会在这死等。 
    
 );
    
    
    
    
    AI助手

This function indicates a value when either one of the specified objects is in the signaling state, or the timeout interval reaches its timeout limit.

当WaitForMultipleObjects()等到多个内核对象的时候,

如果它的bWaitAll 参数设置为false

其返回值

等于 WAIT_OBJECT_0 + lpHandles数组的序号(从0开始计数)

如果,多个都有内核被同时触发,有信号,则返回其中序号最小的那个。

判断: 主线程 判断 子线程 是否预处理成功

复制代码
  //等待事件开始,或者线程结束

    
 	// wait for either capture to start or the thread to end
    
 	HANDLE waitArray[2] = { hStartedEvent, hThread };
    
 	DWORD dwWaitResult;
    
 	dwWaitResult = WaitForMultipleObjects(
    
 		ARRAYSIZE(waitArray), waitArray,
    
 		FALSE, INFINITE
    
 		);
    
 	//线程结束了,但此时hStartedEvent还没有信号,说明线程在初始化阶段 失败了
    
 	if (WAIT_OBJECT_0 + 1 == dwWaitResult) {
    
 		printf("Thread aborted before starting to loopback capture: hr = 0x%08x\n", threadArgs.hr);
    
 		CloseHandle(hStartedEvent);
    
 		CloseHandle(hThread);
    
 		CloseHandle(hStopEvent);
    
 		return -__LINE__;
    
 	}
    
 	//未预期的错误
    
 	if (WAIT_OBJECT_0 != dwWaitResult) {
    
 		printf("Unexpected WaitForMultipleObjects return value %u", dwWaitResult);
    
 		CloseHandle(hStartedEvent);
    
 		CloseHandle(hThread);
    
 		CloseHandle(hStopEvent);
    
 		return -__LINE__;
    
 	}
    
 	//线程初始化成功,关闭开始事件,线程执行无限循环阶段
    
 	CloseHandle(hStartedEvent);
    
    
    
    
    AI助手

结束: 主线程结束子线程

将结束事件设置为有信号

SetEvent(hStopEvent);

子线程在循环过程中,要判断结束事件是否有信号,有则结束

复制代码
     HANDLE waitArray[2] = { hStopEvent, hWakeUp };

    
  
    
 		//子线程在循环过程中判断
    
     dwWaitResult = WaitForMultipleObjects(
    
         ARRAYSIZE(waitArray), waitArray,
    
         FALSE, INFINITE
    
     );
    
     //主线程将结束事件设置为有信号,子线程循环过程中判断 若有信号,则结束循环
    
     if (WAIT_OBJECT_0 == dwWaitResult) {
    
         printf("Received stop event after %u passes and %u frames\n", nPasses, *pnFrames);
    
         bDone = true;
    
         continue; // exits loop
    
     }
    
    
    
    
    AI助手

2 结束进程

在某些情况下,在某些特定场景下(如未完成的任务或异常中断时),常规处理流程未能完成当前任务。此时可通过强行终止进程的操作来完成当前任务的处理。

复制代码
  BOOL KillProcessFromPidT(int nPid)

    
 	{
    
 		DWORD dwProcessID = nPid;
    
 		HANDLE hProcess = ::OpenProcess(PROCESS_TERMINATE, FALSE, dwProcessID);
    
 		::TerminateProcess(hProcess, 0);
    
 		CloseHandle(hProcess);
    
  
    
 		return true;
    
 	}
    
    
    
    
    AI助手
复制代码
                      int nPid = _getpid();

    
 				KillProcessFromPidT(nPid);
    
    
    
    
    AI助手

全部评论 (0)

还没有任何评论哟~