के साथ ओवरलैप्ड/गैर-ओवरलैप मुझे खेद है कि यह एक प्रश्न का अधिक नहीं है, लेकिन इन विशेष चीज़ों के साथ लोगों को समस्या रखने में मदद करने के लिए अधिक से अधिक। जिस समस्या पर मैं काम कर रहा हूं उसे सीरियल I/O के उपयोग की आवश्यकता है, लेकिन मुख्य रूप से विंडोज सीई 6.0 के तहत चल रहा है। हालांकि, मुझे हाल ही में पूछा गया था कि क्या विंडोज़ के तहत भी काम करने के लिए आवेदन किया जा सकता है, इसलिए मैंने इस समस्या को हल करने के बारे में बताया। मैंने यह देखने के लिए काफी समय बिताया कि क्या किसी के पास जवाब हैं जो मैं ढूंढ रहा था और यह सब कुछ गलतफहमी और चीजों के रूप में सामने आया जो कुछ मामलों में मूल रूप से गलत थे। इसलिए इस समस्या को हल करने के बाद, मैंने सोचा कि मैं अपने निष्कर्षों को हर किसी के साथ साझा करूंगा ताकि इन कठिनाइयों का सामना करने वाले किसी भी व्यक्ति के पास जवाब हों।सीरियल I/O ओवरलैप/विंडोज/विंडोज सीई
विंडोज सीई के तहत, ओवरलैप्टेड I/O समर्थित नहीं है। इसका मतलब है कि धारावाहिक बंदरगाह के माध्यम से द्वि-दिशात्मक संचार काफी परेशानी हो सकती है। मुख्य समस्या यह है कि जब आप सीरियल पोर्ट से डेटा पर इंतजार कर रहे हैं, तो आप डेटा नहीं भेज सकते हैं क्योंकि ऐसा करने से आपके मुख्य थ्रेड को रीड ऑपरेशन पूर्ण होने या टाइमआउट तक अवरुद्ध कर दिया जाएगा (इस पर निर्भर करता है कि आपने टाइमआउट सेट किया है या नहीं)
सीरियल I/O करने वाले अधिकांश लोगों की तरह, मेरे पास सीरियल पोर्ट पढ़ने के लिए एक पाठक सीरियल थ्रेड स्थापित किया गया था, जो सीरियल डेटा की प्रतीक्षा करने के लिए एक EV_RXCHAR मास्क के साथ WaitCommEvent() का उपयोग करता था। अब यह वह जगह है जहां विंडोज और विंडोज सीई के साथ कठिनाई उत्पन्न होती है।
अगर मैं इस तरह एक साधारण पाठक धागा, एक उदाहरण के रूप है: -
UINT SimpleReaderThread(LPVOID thParam)
{
DWORD eMask;
WaitCommEvent(thParam, &eMask, NULL);
MessageBox(NULL, TEXT("Thread Exited"), TEXT("Hello"), MB_OK);
}
ऊपर के उदाहरण में
जाहिर है, मैं सीरियल पोर्ट या कुछ भी से डाटा पढ़ने नहीं कर रहा हूँ और मैं यह सोचते हैं रहा हूँ कि thParam में कॉम पोर्ट आदि के लिए खुले हैंडल शामिल हैं। अब, समस्या तब होती है जब आपका धागा WaitCommEvent() को निष्पादित करता है और हिट करता है, आपका पाठक थ्रेड सीरियल पोर्ट डेटा के लिए प्रतीक्षा करने के लिए सो जाएगा। ठीक है, यह ठीक है और जैसा होना चाहिए, लेकिन ... आप इस धागे को कैसे समाप्त करते हैं और संदेशबॉक्स() को प्रकट करने के लिए कैसे मिलता है? खैर, जैसा कि यह पता चला है, यह वास्तव में इतना आसान नहीं है और विंडोज सीई और विंडोज के बीच एक मौलिक अंतर है जिस तरह से यह सीरियल I/O करता है।
विंडोज सीई के तहत, आप WaitCommEvent() को SetCommMask (COMMPORT_HANDLE, 0) या यहां तक कि CloseHandle (COMMPORT_HANDLE) के माध्यम से गिरने के लिए कुछ चीजें कर सकते हैं। यह आपको अपने धागे को सही तरीके से समाप्त करने की अनुमति देगा और इसलिए डेटा भेजने के लिए आपके लिए सीरियल पोर्ट जारी करेगा। हालांकि इन चीजों में से कोई भी विंडोज के तहत काम नहीं करेगा और दोनों थ्रेड का कारण बनेंगे जिन्हें आप उन्हें प्रतीक्षा करने के लिए प्रतीक्षा करेंगे, WaitCommEvent() के पूरा होने पर प्रतीक्षा कर रहे हैं। तो, आप विंडोज के तहत WaitCommEvent() को कैसे समाप्त करते हैं? खैर, आम तौर पर आप ओवरलैप्टेड I/O का उपयोग करेंगे और थ्रेड अवरोधन कोई मुद्दा नहीं होगा, लेकिन चूंकि समाधान को विंडोज सीई के साथ भी संगत होना है, इसलिए ओवरलैप्टेड I/O एक विकल्प नहीं है। WaitCommEvent() को समाप्त करने के लिए विंडोज़ के तहत एक चीज आप कर सकते हैं और यह CancelSynchronousIo() फ़ंक्शन को कॉल करना है और यह आपके WaitCommEvent() को समाप्त कर देगा, लेकिन ध्यान रखें कि यह डिवाइस निर्भर हो सकता है। CancelSynchronousIo() के साथ मुख्य समस्या यह है कि यह विंडोज सीई द्वारा समर्थित नहीं है, इसलिए आप इस समस्या के लिए भाग्य से बाहर हैं!
तो आप इसे कैसे करते हैं? तथ्य यह है कि, इस समस्या को हल करने के लिए, आप बस WaitCommEvent() का उपयोग नहीं कर सकते क्योंकि Windows पर इस फ़ंक्शन को समाप्त करने का कोई तरीका नहीं है जो Windows CE द्वारा समर्थित है। तब वह आपको रीडफाइल() से छोड़ देता है जो फिर से ब्लॉक नहीं करेगा, जबकि यह गैर ओवरलैप्ड I/O पढ़ रहा है और यह होगा कम टाइमआउट के साथ काम करेगा।
रीडफाइल() और एक COMMTIMEOUTS संरचना का उपयोग करने का मतलब यह है कि आपको अपने सीरियल डेटा के लिए एक कसौटी लूप इंतजार करना होगा, लेकिन यदि आपको बड़ी मात्रा में सीरियल डेटा नहीं मिल रहा है, तो यह कोई समस्या नहीं होनी चाहिए। इसके अलावा एक छोटे टाइमआउट के साथ अपने लूप को समाप्त करने के लिए एक कार्यक्रम यह भी सुनिश्चित करेगा कि संसाधन सिस्टम पर वापस आ जाएंगे और आप 100% लोड पर प्रोसेसर को हथियार नहीं दे रहे हैं।नीचे वह समाधान है जिसके साथ मैं आया था और कुछ फीडबैक की सराहना करता हूं, अगर आपको लगता है कि इसे बेहतर किया जा सकता है।
typedef struct
{
UINT8 sync;
UINT8 op
UINT8 dev;
UINT8 node;
UINT8 data;
UINT8 csum;
} COMMDAT;
COMSTAT cs = {0};
DWORD byte_count;
COMMDAT cd;
ZeroMemory(&cd, sizeof(COMMDAT));
bool recv = false;
do
{
ClearCommError(comm_handle, 0, &cs);
if (cs.cbInQue == sizeof(COMMDAT))
{
ReadFile(comm_handle, &cd, sizeof(COMMDAT), &byte_count, NULL);
recv = true;
}
} while ((WaitForSingleObject(event_handle, 2) != WAIT_OBJECT_0) && !recv);
ThreadExit(recv ? cd.data : 0xFF);
तो धागा तुम सिर्फ event_handle में घटना का संकेत समाप्त करने के लिए और है कि आप धागा ठीक से बाहर निकलें और संसाधनों को साफ करने के लिए अनुमति देते हैं और Windows और विंडोज सीई पर सही ढंग से काम करता है।
आशा है कि जो भी मैंने देखा है, उसे इस समस्या से परेशानी हो रही है।
क्यों गतिशील रनटाइम पर CancelSynchronousIo() लोड करने का प्रयास नहीं, और यदि आप सीई नीचे होते हैं तो सिर्फ एक खाली ठूंठ फोन:) निर्धारित करने के लिए मंच और उपयोग डेस्कटॉप पर ओवरलैप हो सकता है? पुस्तकालय का उपयोग डेस्कटॉप पर होने पर ओवरलैप किया गया है, लेकिन विंडोज सीई के तहत गैर-ओवरलैप किया गया है? ऐसा लगता है कि इस समस्या के आसपास चिकनी तरीके हैं। – ctacke
आप डिसमैनिक रूप से CancelSynchronousIo() को लोड नहीं कर सकते हैं, यह एक विंडोज एपीआई फ़ंक्शन है जो कि विंडोज सीई का हिस्सा नहीं है। इसका मुद्दा एक ऐसा समाधान है जो संशोधन के बिना विंडोज सीई और विंडोज दोनों पर काम करता है। विंडोज के लिए एक ओवरलैप्ड संस्करण और Windows CE के लिए एक अलग गैर ओवरलैप्ड एक होने का कोई मतलब नहीं है, जैसा कि आप भी हो सकते हैं, बस # ifdef/# endif और लक्ष्य प्लेटफ़ॉर्म के लिए सशर्त रूप से अपना कोड संकलित करें। –
'SetCommMask' ने हमेशा मेरे लिए' WaitCommEvent' को पूरा करने के लिए हमेशा काम किया है। हालांकि, मेरे कोड में यह हमेशा एक प्रगति को पूरा करने के लिए ट्रिगर कर रहा है 'WaitCommEvent' ओवरलैप किया गया। क्या आप कह रहे हैं कि 'WaitCommEvent' ओवरलैप' SetCommMask' द्वारा पूरा हो जाता है, लेकिन सिंक्रोनस कोई नहीं करता है? –