15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


Deadlock on listbox

Bok Nan Lo -- lo@ia-us.com
Monday, July 22, 1996

Environment: VC++ 4.2 / Win 95/NT

It seemed that attempting to access a listbox in a CView with 2 different 
threads causes a deadlock situation.

Here's the scenario:
1. Both threads access the same function in the view class with a simple 
listbox.AddString()

2. Somewhere in my CDocument object I decided to logoff and thus signal 
these two threads to terminate. Meanwhile, I have WaitForSingleObject (well 
I also tried WaitForMultipleObject with similar results) with INFINITE set 
for timeout value.

3. I expected both threads to terminate since my main thread is already 
sleeping. Unfortunately this is not the case, the main thread slept 
forever, thread 0 exited, thread 1 hung forever. If I change the timeout 
value for WaitForSingleObject to a specified time, I successfully logoff, 
*then*, thread 1 terminated.

All my threads performed as behaved if I do not use the listbox.AddString() 
command.

I've attempted to put a Semaphore around the listbox's AddString() call 
with the same problem.

Anyone with any clue why this strange behaviour?!




Mike Blaszczak -- mikeblas@msn.com
Thursday, July 25, 1996

[Mini-digest: 3 responses]

I answered this exact question from you on CompuServe's MSMFC forum about two 
days ago.

The problem is that you've given your program a bad design. The deadlock 
occurrs because your primary thread isn't pumping messages for the list box -- 
it's blocking on the subordinate threads.  The subordinate thread will never 
terminate, though, because they've called SendMessage() to the list box.  
Since SendMessage() is synchronous, it doesn't return until the message is 
processed.  But the message is never processed because the message pump isn't 
running because the thread which will receive the message is blocking.  The 
deadlock is because the thread receiving the message can't release until the 
sending thread can release, but the sending thread won't release until the 
receiving thread releases.

You need to design deadlocks out of your software.

.B ekiM
http://www.nwlink.com/~mikeblas

----------
From: 	owner-mfc-l@netcom.com on behalf of Bok Nan Lo
Sent: 	Monday, July 22, 1996 10:41 AM
To: 	'mfc-l@netcom.netcom.com'
Subject: 	Deadlock on listbox

Environment: VC++ 4.2 / Win 95/NT

It seemed that attempting to access a listbox in a CView with 2 different 
threads causes a deadlock situation.

Here's the scenario:
1. Both threads access the same function in the view class with a simple 
listbox.AddString()

2. Somewhere in my CDocument object I decided to logoff and thus signal 
these two threads to terminate. Meanwhile, I have WaitForSingleObject (well 
I also tried WaitForMultipleObject with similar results) with INFINITE set 
for timeout value.

3. I expected both threads to terminate since my main thread is already 
sleeping. Unfortunately this is not the case, the main thread slept 
forever, thread 0 exited, thread 1 hung forever. If I change the timeout 
value for WaitForSingleObject to a specified time, I successfully logoff, 
*then*, thread 1 terminated.

All my threads performed as behaved if I do not use the listbox.AddString() 
command.

I've attempted to put a Semaphore around the listbox's AddString() call 
with the same problem.

Anyone with any clue why this strange behaviour?!


-----From: Tim Hagemann <100063.323@CompuServe.COM>

Bok,

Tried you to share a CListCtrl-Object in different threads? If you did, this
might be the problem. MFC stores the hWnd - CWnd map in the
AFX_MODULE_THREAD_STATE class, which is local to thread and module. So it is
generally not a good idea to share CWnd derived objects in different threads. I
tried this sometimes on my own, the result was always an assertion in the MFC
code.
Just try to add the string via the normal Win32 API, so call 

::SendMessage(listbox.m_hWnd,0,YourString);

Hope this helps !


Tim Hagemann
ifa informationssysteme fuer Augenaerzte
-----From: Gordon Weakliem 

Probably, CListBOx::AddString() devolves into ::SendMessage( hwndlist,
LB_ADDSTRING...)  SendMessage also causes a context switch _if_ the thread
sending the message is not the thread that owns the destination message
queue. So, I'm guessing that one thread creates the list box and owns it's
message queue, and when this thread decides to terminate, and does
WaitForSingleObject, one of your threads is trying to do an AddString.
AddString is waiting for the context switch, and your target thread is
waiting for the other thread to die.  That's one situation where the
deadlock you describe could occur.
Gordon Weakliem
gweakl@metronet.com





| Вернуться в корень Архива |