मैं std::thread और std::async को लेकर बहुत भ्रमित हूं। यहाँ मेरा कोड है:

#include <vector>
#include <thread>
#include <mutex>

std::vector<int> myvector = {};
std::mutex mu;
int result;

void samplefunc(int a, int& result){
    result = 2 * a;
}

void func1(){
    while(true){
        std::unique_lock locker(mu);
        locker.lock();
        std::vector<int> temp = myvector;
        locker.unlock();
        if(myvector.size() > 0){
            samplefunc(myvector.at(0),result);
            myvector.clear();
        }else{
            samplefunc(0,result);
        }
    }
}

void func2(){
    while(true){
        //do complex things, suppose after complex calculations we have result dummy which is type int
        int dummy = 0;
        std::unique_lock locker(mu);
        locker.lock();
        myvector.push_back(dummy);
        locker.unlock();
    }
}

int main(){
    std::thread t1(func1);
    std::thread t2(func2);
    t1.join();
    t2.join();
}

मैं जो करना चाहता हूं वह बहुत आसान है। हमारे पास दो धागे हैं जो समानांतर में चलने चाहिए (अर्थात उन्हें एक दूसरे पर प्रतीक्षा करने की आवश्यकता नहीं है)। हालांकि, यदि थ्रेड t2 किसी साझा वेक्टर में कुछ पूर्णांक रखता है, तो थ्रेड t1 को अपना व्यवहार बदलना चाहिए। क्या ऊपर दिया गया कोड इसे प्राप्त करता है, या हमें std::async, std::future, आदि का उपयोग करना चाहिए?

2
eet 30 सितंबर 2021, 18:23

1 उत्तर

सबसे बढ़िया उत्तर

यदि साझा डेटा ठीक से सिंक्रनाइज़ किया गया है, तो अलग थ्रेड में उस डेटा का उपयोग करके गणना को प्रभावित करने के लिए साझा डेटा पर एक थ्रेड से संशोधन के लिए ठीक है। लेकिन आपने myvector को पर्याप्त रूप से लॉक नहीं किया है। लॉक को साझा किए गए डेटा पर सभी पठन चरणों को घेरना होगा। func1 में, आप लॉक को बहुत जल्दी छोड़ देते हैं।

2
WilliamClements 30 सितंबर 2021, 18:45
हां, मुझे अभी एहसास हुआ कि चूंकि मैं लॉक के बाहर वेक्टर को साफ करता हूं, इसलिए मुझे स्पष्ट प्रक्रिया के बाद अनलॉक करना चाहिए। तो std :: async की कोई आवश्यकता नहीं है, है ना?
 – 
eet
30 सितंबर 2021, 18:54
1
आपको मैन्युअल रूप से लॉक/अनलॉक नहीं करना चाहिए। unique_lock का कंस्ट्रक्टर म्यूटेक्स को लॉक करता है, और इसका डिस्ट्रक्टर इसे अनलॉक करता है। वास्तव में, आपका मैनुअल lock() अपवाद होना चाहिए क्योंकि unique_lock में एक बार में एकाधिक लॉक नहीं हो सकते।
 – 
Remy Lebeau
30 सितंबर 2021, 19:00
1
std::unique_lock के कंस्ट्रक्टर को लॉक करने दें। आपको इसे मैन्युअल रूप से करने की आवश्यकता नहीं है। यदि आप लॉकिंग अवधि को स्कोप करना चाहते हैं तो आप ब्लॉक का उपयोग कर सकते हैं
 – 
Mgetz
30 सितंबर 2021, 19:07
इंगित करने के लिए धन्यवाद। क्षमा करें, कोई locker.lock() बिल्कुल नहीं होना चाहिए। बस locker.unlock() पर्याप्त है।
 – 
eet
30 सितंबर 2021, 19:11
यहां तक ​​​​कि यह अनावश्यक है, आप लॉक को समाप्त करने के लिए केवल एक मानक ब्लॉक का उपयोग कर सकते हैं। लॉक का विनाशक म्यूटेक्स जारी करेगा
 – 
Mgetz
30 सितंबर 2021, 19:12