PostMessage أحيانا يفقد رسالة
-
22-07-2019 - |
سؤال
كتبت متعددة الخيوط تطبيق ويندوز حيث الموضوع:
A – هو نموذج windows الذي يتعامل مع تفاعل المستخدم ومعالجة البيانات من B.
ب – أحيانا يولد البيانات ويمررها اثنين A.
موضوع آمنة طابور يستخدم لتمرير البيانات من مؤشر ترابط B إلى A.على إدراج بقائمة الانتظار و dequeue مهام حراسة باستخدام ويندوز الحرجة قسم الكائنات.
إذا كانت قائمة الانتظار فارغة عند إدراج بقائمة الانتظار استدعاء الدالة استخدام PostMessage أن أقول أن هناك البيانات في قائمة الانتظار.وظيفة الشيكات للتأكد من الدعوة إلى PostMessage يتم تنفيذها بنجاح و يدعو مرارا وتكرارا PostMessage إذا لم يكن ناجحا (PostMessage لم تفشل).
هذا يعمل جيدا لبعض الوقت حتى كمبيوتر واحد معين بدأت تفقد رسالة في بعض الأحيان.خلال تفقد أعني أن PostMessage يعود بنجاح في ب ولكن لم يتلقى الرسالة.يؤدي هذا البرنامج تظهر المجمدة.
لدي بالفعل التوصل إلى عدة مقبول الحلول.أنا مثيرة للاهتمام في معرفة لماذا يقوم نظام ويندوز هو فقدان هذه الرسائل و لماذا هذا يحدث فقط على جهاز كمبيوتر واحد.
هنا هو الأجزاء ذات الصلة من القانون.
// Only called by B
procedure TSharedQueue.Enqueue(AItem: TSQItem);
var
B: boolean;
begin
EnterCriticalSection(FQueueLock);
if FCount > 0 then
begin
FLast.FNext := AItem;
FLast := AItem;
end
else
begin
FFirst := AItem;
FLast := AItem;
end;
if (FCount = 0) or (FCount mod 10 = 0) then // just in case a message is lost
repeat
B := PostMessage(FConsumer, SQ_HAS_DATA, 0, 0);
if not B then
Sleep(1000); // this line of code has never been reached
until B;
Inc(FCount);
LeaveCriticalSection(FQueueLock);
end;
// Only called by A
function TSharedQueue.Dequeue: TSQItem;
begin
EnterCriticalSection(FQueueLock);
if FCount > 0 then
begin
Result := FFirst;
FFirst := FFirst.FNext;
Result.FNext := nil;
Dec(FCount);
end
else
Result := nil;
LeaveCriticalSection(FQueueLock);
end;
// procedure called when SQ_HAS_DATA is received
procedure TfrmMonitor.SQHasData(var AMessage: TMessage);
var
Item: TSQItem;
begin
while FMessageQueue.Count > 0 do
begin
Item := FMessageQueue.Dequeue;
// use the Item somehow
end;
end;
المحلول
هو FCount
كما يحميها FQueueLock
?إذا المشكلة تكمن مع FCount
يتم زيادة بعد نشر الرسالة المجهزة مسبقا.
هنا ما يمكن أن يحدث:
- ب يدخل الحرجة القسم
- ب المكالمات
PostMessage
- وهو يتلقى الرسالة ولكن لا تفعل أي شيء منذ
FCount
هو0
- ب الزيادات
FCount
- ب يترك مقطع حرج
- يجلس هناك مثل البطة
سريع العلاج سيكون على الاضافة FCount
قبل استدعاء PostMessage
.
نضع في اعتبارنا أن الأشياء يمكن أن يحدث أسرع مما يتوقع المرء (أيالرسالة وشارك مع PostMessage الوقوع ومعالجتها من قبل مؤشر ترابط آخر قبل لديك فرصة لزيادة FCount بضعة أسطر في وقت لاحق) ، وخصوصا عندما كنت في صحيح متعددة الخيوط البيئة (وحدات المعالجة المركزية المتعددة).هذا هو السبب في أنني طلبت في وقت سابق إن "مشكلة الجهاز" كان عدة وحدات المعالجة المركزية/النوى.
طريقة سهلة لاستكشاف مشاكل مثل هذه سقالة رمز مع الاضافيه تسجيل الدخول في كل مرة تقوم بإدخال طريقة دخول/مغادرة مقطع حرج.... الخثم يمكنك تحليل سجل لمشاهدة صحيح ترتيب الأحداث.
على صعيد منفصل, لطيفة قليلا الأمثل الذي يمكن القيام به في المنتج/المستهلك مثل هذا السيناريو هو استخدام اثنين من قوائم الانتظار بدلا من واحدة.عندما المستهلك يستيقظ إلى عملية كاملة الانتظار ، يمكنك مبادلة الكامل الطابور فارغ واحد فقط قفل/العملية الكاملة الانتظار بينما جديدة قائمة الانتظار فارغة يمكن ملؤها من دون اثنين من المواضيع تحاول قفل كل منهما قوائم الانتظار.كنت لا تزال بحاجة إلى بعض تأمين في مبادلة اثنين من طوابير على الرغم من.
نصائح أخرى
إذا قائمة الانتظار فارغ عند إدراج بقائمة الانتظار يتم استدعاء الدالة، فإن وظيفة استخدام PostMessage أن أقول أن هناك A هي البيانات في قائمة الانتظار.
اقتباس فقرة> هل تأمين قائمة انتظار الرسالة قبل التحقق من حجم الطابور وإصدار PostMessage
؟ قد تكون تعاني من حالة سباق حيث قمت بالتدقيق في قوائم الانتظار وتجد أنه من غير فارغة في حين أن هناك بمعالجة الرسالة الأخيرة جدا وعلى وشك أن يذهب الخمول.
لمعرفة ما إذا كنت في الواقع تعاني من حالة تعارض وليست مشكلة مع PostMessage
، هل يمكن أن التحول إلى استخدام هذا الحدث. إن ترابط العامل (A) الانتظار على الحدث بدلا من انتظار رسالة. سوف B ببساطة تعيين هذا الحدث بدلا من نشر الرسالة.
وهذا يعمل بشكل جيد لبعض الوقت حتى بدأ جهاز كمبيوتر واحد محدد ل تفقد رسالة من حين لآخر.
اقتباس فقرة>وقبل أي فرصة، لا عدد وحدات المعالجة المركزية أو النوى أن هذه كمبيوتر معين يكون مختلفا عن الآخرين حيث كنت لا أرى أي مشكلة؟ في بعض الأحيان عند التبديل من جهاز واحد وحدة المعالجة المركزية للجهاز مع أكثر من البدني وحدة المعالجة المركزية / الأساسية، قد تنشأ ظروف سباق جديدة أو الجمود.
ويمكن أن يكون هناك مثيل الثاني على التوالي تدري وتناول الرسائل، وسم لهم كما عالجت؟