我打電話給IMFSourceReader::ReadSample,我發現如果它無法讀取資料就會卡住。
所以我試圖通過 TerminateThread() 終止執行緒,但它回傳 0 作為失敗。
我怎樣才能終止卡住的執行緒?
這是我的示例代碼:
#include <iostream>
#include <vector>
#include <codecvt>
#include <string>
#include <thread>
#include <mutex>
#include <chrono>
#include <condition_variable>
#include <Windows.h>
using namespace std::chrono_literals;
class MyObject
{
private:
...
std::thread *t;
std::mutex m;
std::condition_variable cv;
std::thread::native_handle_type handle;
int getsample(uint8_t* data)
{
// call a ReadSample
hr = pVideoReader->ReadSample(
MF_SOURCE_READER_ANY_STREAM, // Stream index.
0, // Flags.
&streamIndex, // Receives the actual stream index.
&flags, // Receives status flags.
&llTimeStamp, // Receives the time stamp.
&pSample // Receives the sample or NULL.
);
...
return 0;
}
int myfunc_wrapper(uint8_t* data)
{
int ret = 0;
BOOL bpass = 0;
if (t == nullptr) {
t = new std::thread([this, &data, &ret]()
{
ret = this->getsample(data);
this->cv.notify_one();
});
handle = t->native_handle();
t->detach();
}
{
std::unique_lock<std::mutex> l(this->m);
if (this->cv.wait_for(l, 2500ms) == std::cv_status::timeout) {
bpass = TerminateThread(handle, 0);
if (bpass == 0) {
std::cout << "TerminateThread Fail! " << GetLastError() << std::endl;
}
throw std::runtime_error("Timeout Fail 2500 ms");
}
}
delete t;
t = nullptr;
}
public:
int my_func(uint8_t* raw_data)
{
bool timedout = false;
try {
if (myfunc_wrapper(raw_data) != 0)
return -1;
}
catch (std::runtime_error& e) {
std::cout << e.what() << std::endl;
timedout = true;
}
if (timedout)
return -1;
return 0;
}
};
int main()
{
uint8_t data[512];
MyObject* obj = new MyObject();
while (true)
{
obj->my_func(data);
}
return 0;
}
輸出:
TerminateThread Fail! 6
Timeout Fail 2500 ms
TerminateThread Fail! 6
Timeout Fail 2500 ms
...
我也嘗試使用 pthread_cancel 但它無法編譯,因為存在型別錯誤。
不存在將“std::thread::native_handle_type”轉換為“__ptw32_handle_t”的合適建構式
handle = t->native_handle();
...
pthread_cancel(handle); // no suitable constructor exists to convert
uj5u.com熱心網友回復:
它未能終止的原因是本機句柄在分離后不再有效,您可以這樣做的一種方法是OpenThread使用執行緒 ID 來獲取新句柄。
要獲取執行緒 ID,您可以在分離之前使用它的句柄,如下所示:
DWORD nativeId = GetThreadId(t->native_handle());
t->detach();
之后,只需打開執行緒的新句柄即可終止它:
HANDLE hThread = OpenThread(THREAD_TERMINATE, FALSE, nativeId);
if (hThread)
{
BOOL result = TerminateThread(hThread, 0);
CloseHandle(hThread);
}
但是你不應該這樣做,考慮其他方式來通知執行緒自行終止。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/520359.html
標籤:C 多线程
