यहां हम देखेंगे कि C++11 में थ्रेड्स को कैसे समाप्त किया जाए। C++11 में थ्रेड्स को समाप्त करने की कोई सीधी विधि नहीं है।
std::future<void> का उपयोग थ्रेड को सिग्नल करने के लिए किया जा सकता है, और जब फ्यूचर में मान उपलब्ध हो तो इसे बाहर निकलना चाहिए। यदि हम थ्रेड को सिग्नल भेजना चाहते हैं लेकिन वास्तविक मान नहीं भेजना चाहते, तो हम void टाइप ऑब्जेक्ट पास कर सकते हैं।
चरण
- प्रॉमिस ऑब्जेक्ट बनाएं:
std::promise<void> exitSignal; - एसोसिएटेड फ्यूचर प्राप्त करें:
std::future<void> futureObj = exitSignal.get_future(); - थ्रेड बनाते समय फ्यूचर पास करें:
std::thread th(&threadFunction, std::move(futureObj)); - समाप्त करने के लिए:
exitSignal.set_value();कॉल करें
उदाहरण
#include <thread>
#include <iostream>
#include <cassert>
#include <chrono>
#include <future>
using namespace std;
void threadFunction(future<void> future) {
cout << "थ्रेड शुरू हो रहा है" << endl;
// फ्यूचर पर वेट करें टाइमआउट के साथ
while (future.wait_for(chrono::milliseconds(1)) == future_status::timeout) {
cout << "थ्रेड निष्पादित हो रहा है....." << endl;
this_thread::sleep_for(chrono::milliseconds(500)); // 500ms वेट
}
cout << "थ्रेड समाप्त हुआ" << endl;
}
int main() {
promise<void> signal_exit; // प्रॉमिस ऑब्जेक्ट बनाएं
future<void> future = signal_exit.get_future(); // फ्यूचर ऑब्जेक्ट प्राप्त करें
thread my_thread(&threadFunction, std::move(future)); // थ्रेड शुरू करें, फ्यूचर मूव करें
this_thread::sleep_for(chrono::seconds(7)); // 7 सेकंड वेट करें
cout << "थ्रेड जल्द ही रोका जाएगा...." << endl;
signal_exit.set_value(); // प्रॉमिस में मान सेट करें (सिग्नल भेजें)
my_thread.join(); // थ्रेड को मुख्य थ्रेड के साथ जोड़ें
cout << "मुख्य फ़ंक्शन में कार्य कर रहे हैं" << endl;
return 0;
}
आउटपुट
थ्रेड शुरू हो रहा है थ्रेड निष्पादित हो रहा है..... थ्रेड निष्पादित हो रहा है..... थ्रेड निष्पादित हो रहा है..... थ्रेड निष्पादित हो रहा है..... थ्रेड निष्पादित हो रहा है..... थ्रेड निष्पादित हो रहा है..... थ्रेड निष्पादित हो रहा है..... थ्रेड निष्पादित हो रहा है..... थ्रेड निष्पादित हो रहा है..... थ्रेड निष्पादित हो रहा है..... थ्रेड निष्पादित हो रहा है..... थ्रेड निष्पादित हो रहा है..... थ्रेड निष्पादित हो रहा है..... थ्रेड निष्पादित हो रहा है..... थ्रेड जल्द ही रोका जाएगा.... थ्रेड समाप्त हुआ मुख्य फ़ंक्शन में कार्य कर रहे हैं
वैकल्पिक दृष्टिकोण
1. एटॉमिक फ्लैग (सरल, पोलिंग)
#include <atomic>
#include <thread>
#include <chrono>
atomic<bool> stop_flag{false};
void worker() {
while (!stop_flag.load()) {
// काम करें
this_thread::sleep_for(chrono::milliseconds(100));
}
}
int main() {
thread t(worker);
this_thread::sleep_for(chrono::seconds(2));
stop_flag.store(true); // सिग्नल स्टॉप
t.join();
}
2. कंडीशन वेरिएबल (कुशल वेटिंग)
#include <condition_variable>
#include <mutex>
#include <thread>
mutex mtx;
condition_variable cv;
bool stop = false;
void worker() {
unique_lock<mutex> lock(mtx);
while (!stop) {
cv.wait_for(lock, chrono::milliseconds(100));
if (!stop) {
// काम करें
}
}
}
int main() {
thread t(worker);
this_thread::sleep_for(chrono::seconds(2));
{
lock_guard<mutex> lock(mtx);
stop = true;
}
cv.notify_one();
t.join();
}
3. C++20: std::jthread (ऑटो-जॉइनिंग)
#include <thread>
#include <chrono>
#include <iostream>
void worker(stop_token st) {
while (!st.stop_requested()) {
cout << "काम कर रहे हैं...\n";
this_thread::sleep_for(chrono::milliseconds(500));
}
cout << "रुक गए\n";
}
int main() {
jthread t(worker); // jthread: ऑटोमैटिक जॉइन
this_thread::sleep_for(chrono::seconds(2));
t.request_stop(); // रुकने का अनुरोध
// t ऑटोमैटिकली जॉइन होता है जब स्कोप से बाहर जाता है
}
तुलना
| विधि | C++ संस्करण | जटिलता | दक्षता | सिफारिश |
|---|---|---|---|---|
| promise/future | C++11 | मध्यम | अच्छी | वन-टाइम सिग्नलिंग |
| atomic फ्लैग | C++11 | सरल | पोलिंग ओवरहेड | सरल मामले |
| condition_variable | C++11 | उच्च | उत्कृष्ट | जटिल सिंक्रोनाइज़ेशन |
| jthread + stop_token | C++20 | सरल | उत्कृष्ट | आधुनिक C++ (सर्वश्रेष्ठ) |
नोट: std::thread का कोई terminate() या stop() मेथड नहीं है (जावा के विपरीत)। सहयोगात्मक रद्दीकरण (cooperative cancellation) पैटर्न का उपयोग करें।