क्यूटी विजेट्स में मल्टीथ्रेडिंग

एक विंडो इंटरफ़ेस के साथ एक एप्लिकेशन चलाते समय, यह सुनिश्चित करना महत्वपूर्ण है कि कोई फ्रीज न हो। इसके लिए, जटिल गणना को एक अलग धागे में चलाया जाना चाहिए। बहु-थ्रेडेड एप्लिकेशन की अवधारणा Qt सिग्नल-स्लॉट दृष्टिकोण के साथ अच्छी तरह से जाती है, जिसमें किसी भी रन () विधि को फिर से परिभाषित करने की आवश्यकता नहीं है।

मुख्य विचार। एक बहु-थ्रेडेड अनुप्रयोग में, गणना एक अलग थ्रेड में की जाती है, जिसके अंत में एक संकेत उत्सर्जित होता है, जिसके परिणामस्वरूप उसके तर्कों को प्रसारित किया जाता है। मेनविंडो के स्वामित्व वाले एक स्लॉट को कहा जाएगा। गणना के परिणाम स्लॉट के तर्कों में होंगे और उन्हें आउटपुट करना मुश्किल नहीं होगा।

माइक्रोकंट्रोलर्स के साथ एक सादृश्य आरेखण, एक संकेत एक बाधा वेक्टर के साथ एक संक्रमण है, और एक स्लॉट स्वयं एक बाधा हैंडलर है। "बाधित" होने के लिए, संकेत उत्सर्जित होना चाहिए: mysignalvoid () का उत्सर्जन करें; तब Qt एक "हैंडलर" (स्लॉट) के साथ इसकी तलाश शुरू कर देगा। Qt में, आप एक सिग्नल पर कई स्लॉट्स लटका सकते हैं।

निम्नलिखित आंकड़ा डेमो एप्लिकेशन के एल्गोरिथ्म को दर्शाता है। हर दूसरे के प्रसंस्करण का धागा किंवदंती एक यूएसबी छिपाई डिवाइस के अनुसार पूछताछ करता है। फिर एक एमिट सिग्नल उत्सर्जित किया जाता है, जो एक स्लॉट को संसाधित करता है जो पहले से ही मेनविन्डो से संबंधित है और जिसके अनुसार फार्म पर आकर्षित करने की क्षमता है।



तो, हमारे पास कक्षाएं हैं जो सिग्नल-स्लॉट दृष्टिकोण का उपयोग कर सकते हैं। ऐसा करने के लिए, उनकी घोषणा Q_OBJECT मैक्रो का उपयोग करती है।

class Worker : public QObject { Q_OBJECT //   -   public: QTimer *timerDeviceRead; //      GuiUpdateCallback Worker(); public slots: void updateElectropipData(); signals: void GuiUpdatePlease(uint8_t const *arrptr,size_t); }; class MainWindow : public QMainWindow //   GUI { Q_OBJECT public slots: void GuiUpdateCallback(uint8_t const *arrptr, size_t); private: Ui::MainWindow *ui; //       QThread *thread; 

तर्कों में गणनाओं के परिणाम को पारित करने के लिए, तर्कों के लिए उपयोग किए जाने वाले प्रकारों को पंजीकृत करना आवश्यक है। आप इसे अलग-अलग जगहों पर कर सकते हैं, लेकिन आमतौर पर वर्ग के निर्माता में, जो बाद में इन प्रकारों के साथ काम करेगा:

 Worker::Worker(){ qRegisterMetaType<std::size_t>("size_t"); qRegisterMetaType<uint8_t const *>("uint8_t const *"); 


अगला, प्रसंस्करण धागे के निर्माण में एक टाइमर बनाया जाता है। हर दूसरा, अपडेटयूएसडॉट कॉलबैक प्रोसेसिंग स्लॉट कहा जाएगा। Qt5 में सिग्नल-स्लॉट कनेक्शन के सिंटैक्स पर ध्यान दें।

  this->timerDeviceRead = new QTimer(); connect(Worker::timerDeviceRead, &QTimer::timeout, this, &Worker::updateUSBDataCallback); this->timerDeviceRead->start(); 

निम्नलिखित प्रसंस्करण थ्रेड स्लॉट का शरीर है। सभी लंबे समय से सोचा कोड यहाँ होना चाहिए।

 void Worker::updateUSBDataCallback(){ size_t mysize = 65; uint8_t buf[65] = { "I like USB HID" }; emit GuiUpdatePlease(buf,mysize); //  //: for(int i =0;i<64;i++){ buf[i]=i+'0'; if (i+'0' > 250) i=0; } } 

यहां प्रदर्शित करने के लिए, मेनविंडो स्लॉट में सिग्नल उत्सर्जित होने के तुरंत बाद, सरणी की सामग्री को ब्रेज़ेनली संशोधित किया जाता है। और जब से सूचक द्वारा सरणी पारित की जाती है, तो एक गंदा रीड प्राप्त होता है। इस स्थिति को रोकने के लिए, प्रोसेसिंग थ्रेड से सिग्नल को निश्चित तरीके से GuiUpdateCallback () स्लॉट से जोड़ा जाना चाहिए:

 MainWindow::MainWindow{ connect(worker, &Worker::GuiUpdatePlease, this, &MainWindow::GuiUpdateCallback, Qt::BlockingQueuedConnection); 

इस स्थिति में, एक सिग्नल उत्सर्जित करते हुए, प्रसंस्करण धागा को GuiUpdateCallback () स्लॉट के अंत तक अवरुद्ध किया जाता है।

यदि लंबे "uint8_t const *" आपको प्रोग्राम टेक्स्ट में भ्रमित करता है, तो आप पर्यायवाची TUPPP प्राप्त कर सकते हैं:

 typedef uint8_t const * TU8PTR; 

स्रोत कोड

Source: https://habr.com/ru/post/hi485324/


All Articles