C ++ 0x 스레드 중단
C ++ 0x 최종 초안에 따르면 스레드 종료를 요청할 방법이 없습니다. 즉, 필요한 경우 DIY 솔루션을 구현해야합니다.
반면에 boost :: thread는 안전한 방식으로 스레드를 중단하는 메커니즘을 제공합니다 .
귀하의 의견으로는 가장 좋은 해결책은 무엇입니까? 자신 만의 협력적인 '중단 메커니즘'을 설계하고 있습니까?
모든 언어 사양은 지원이 언어에 내장되어 있지 않다고 말합니다. boost::thread::interrupt
스레드 함수의 지원도 필요합니다.
인터럽트 된 스레드가 다음에 지정된 인터럽트 지점 중 하나를 실행할 때 (또는 실행 중 현재 차단 된 경우)
즉, 스레드 함수가 호출자에게 인터럽트 기회를주지 않으면 여전히 멈춰 있습니다.
"원어민 화"란 무엇을 의미하는지 잘 모르겠습니다 boost:threads
..
그래도 저는 명시적인 메커니즘을 사용합니다. 어쨌든 충분한 인터럽트 지점이 있는지 생각해야합니다.이를 명시 적으로 만드는 것은 어떻습니까? 추가 코드는 일반적으로 내 경험상 미미하지만 일부 대기를 단일 객체에서 다중 객체로 변경해야 할 수도 있습니다. 라이브러리에 따라 더보기 좋지 않을 수 있습니다.
또한 "제어 흐름에 예외를 사용하지 마십시오"를 가져올 수 있지만 스레드를 엉망으로 만드는 것과 비교할 때 이것은 단지 지침 일뿐입니다.
기본 핸들을 사용하여 스레드를 취소하는 것은 모든 스택 할당 개체를 삭제해야하므로 C ++에서 잘못된 옵션입니다. 이것이 그들이 취소 작업을 포함하지 않은 주된 이유였습니다.
Boost.Thread는 대기중인 프리미티브를 풀링해야하는 인터럽트 메커니즘을 제공합니다. 이것은 일반적인 메커니즘으로 비용이 많이들 수 있으므로 표준에 포함되지 않았습니다.
직접 구현해야합니다. 내 대답을 참조하십시오 여기에 직접이를 구현하는 방법에 대한 비슷한 질문에. 솔루션을 완료하려면 인터럽트가 참일 때 인터럽트가 발생해야하며 스레드는이 인터럽트를 포착하여 종료해야합니다.
스레드를 종료하는 것은 안전하지 않습니다. 데이터 구조의 상태를 제어 할 수 없기 때문에 그 순간 작업 중이었습니다.
실행중인 스레드를 중단하려면 자체 메커니즘을 구현해야합니다. IMHO가 필요한 경우 디자인은 다중 스레드에 대해 준비되지 않았습니다.
스레드가 끝날 때까지 기다리려면 join () 또는 future를 사용하십시오.
스레드를 선제 적으로 종료하는 것은 전체 프로세스의 상태가 해당 지점 이후에 불확실 해지기 때문에 안전하지 않습니다. 스레드가 종료되기 전에 중요한 섹션을 획득했을 수 있습니다. 이 중요한 섹션은 이제 절대로 공개되지 않습니다. 힙은 영구적으로 잠길 수 있습니다.
boost::thread::interrupt
솔루션은 정중하게 요청하는 방식으로 작동합니다. Boost.Thread 조건 변수를 기다리거나 인터럽트가 호출 된 후 스레드가 이러한 작업 중 하나를 수행하는 경우와 같이 인터럽트 가능한 작업을 수행하는 스레드 만 인터럽트합니다. 그럼에도 불구하고 Win32의 TerminateThread
기능 과 같이 스레드는 무례하게 고기 분쇄기를 통과하지 않습니다. 예를 들어 Win32의 기능이 수행하는 것처럼 단순히 예외를 유발합니다. 이는 잘 작동하는 코더이고 모든 곳에서 RAII를 사용하면 자체적으로 정리됩니다. 스레드를 정상적으로 종료합니다.
DIY 솔루션을 구현하는 것이 가장 합리적이며 실제로 그렇게 어렵지 않아야합니다. 스레드가 종료되도록 요청되는지 여부를 나타내는 동 기적으로 읽고 쓰는 공유 변수가 필요하며 스레드가 안전하게 중단 될 수있는 상태에있을 때이 변수에서 주기적으로 읽습니다. 스레드를 중단하려면이 변수에 동기식으로 작성한 다음 스레드에 가입하면됩니다. 적절하게 협력한다고 가정하면 변수가 작성되고 종료되어 조인 함수가 더 이상 차단되지 않음을 알 수 있습니다.
당신이 원주민으로 가면 아무것도 얻지 못할 것입니다. 표준 및 크로스 플랫폼 OOP 스레딩 메커니즘의 모든 이점을 그냥 버리면됩니다. 코드가 정확하려면 스레드가 협력 적으로 종료되어야합니다. 이는 위에서 설명한 통신을 의미합니다.
다음은 스레드 취소 기의 겸손한 구현입니다 (C ++ 0x 용). 도움이 되길 바랍니다.
// Class cancellation_point
#include <mutex>
#include <condition_variable>
struct cancelled_error {};
class cancellation_point
{
public:
cancellation_point(): stop_(false) {}
void cancel() {
std::unique_lock<std::mutex> lock(mutex_);
stop_ = true;
cond_.notify_all();
}
template <typename P>
void wait(const P& period) {
std::unique_lock<std::mutex> lock(mutex_);
if (stop_ || cond_.wait_for(lock, period) == std::cv_status::no_timeout) {
stop_ = false;
throw cancelled_error();
}
}
private:
bool stop_;
std::mutex mutex_;
std::condition_variable cond_;
};
// Usage example
#include <thread>
#include <iostream>
class ThreadExample
{
public:
void start() {
thread_ = std::unique_ptr<std::thread>(
new std::thread(std::bind(&ThreadExample::run, this)));
}
void stop() {
cpoint_.cancel();
thread_->join();
}
private:
void run() {
std::cout << "thread started\n";
try {
while (true) {
cpoint_.wait(std::chrono::seconds(1));
}
} catch (const cancelled_error&) {
std::cout << "thread cancelled\n";
}
}
std::unique_ptr<std::thread> thread_;
cancellation_point cpoint_;
};
int main() {
ThreadExample ex;
ex.start();
ex.stop();
return 0;
}
내 스레드 구현은 pimpl 관용구를 사용하고 Impl 클래스에는 지원하는 각 OS에 대해 하나의 버전과 부스트를 사용하는 버전이 있으므로 프로젝트를 빌드 할 때 사용할 버전을 결정할 수 있습니다.
두 가지 클래스를 만들기로 결정했습니다. 하나는 기본, OS 제공 서비스 만있는 스레드입니다. 다른 하나는 SafeThread로 Thread에서 상속되며 협업 중단 방법이 있습니다.
Thread has a terminate() method that does an intrusive termination. It is a virtual method which is overloaded in SafeThread, where it signals an event object. There's a (static) yeld() method which the running thread should call from time to time; this methods checks if the event object is signaled and, if yes, throws an exception caught at the caller of the thread entry point, thereby terminating the thread. When it does so it signals a second event object so the caller of terminate() can know that the thread was safely stopped.
For cases in which there's a risk of deadlock, SafeThread::terminate() can accept a timeout parameter. If the timeout expires, it calls Thread::terminate(), thus killing intrusively the thread. This is a last-resource when you have something you can't control (like a third-party API) or in situations in which a deadlock does more damage than resource leaks and the like.
Hope this'll be useful for your decision and will give you a clear enough picture about my design choices. If not, I can post code fragments to clarify if you want.
I agree with this decision. For example, .NET allows to abort any worker thread, and I never use this feature and don't recommend to do this to any professional programmer. I want to decide myself, when a worker thread may be interrupted, and what is the way to do this. It is different for hardware, I/O, UI and other threads. If thread may be stopped at any place, this may cause undefined program behavior with resource management, transactions etc.
ReferenceURL : https://stackoverflow.com/questions/2790346/c0x-thread-interruption
'IT story' 카테고리의 다른 글
SAX 모델 용 XPath 프로세서가 있습니까? (0) | 2020.12.31 |
---|---|
누군가 신용 카드 데이터를 저장하고 있습니다. 어떻게 처리하고 있습니까? (0) | 2020.12.31 |
node.js 비동기 라이브러리 (0) | 2020.12.31 |
사용자 정의 녹아웃 바인딩을 위해 초기화와 업데이트 사이에 상태를 저장하는 선호하는 방법은 무엇입니까? (0) | 2020.12.31 |
PHP umask (0) 목적은 무엇입니까 (0) | 2020.12.31 |