Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

OpenMP and windows

Peter_K_2
Beginner
1,022 Views
I must admit that I am new to OpenMP and still trying to understand all of it.

I am trying to create a windows program that uses OPENMP and trying to update a listbox with information from each thread that is created. I am using the command
lret = SendDlgItemMessage(hdlg,IDC_LIST1,LB_ADDSTRING,0,LOC(msg))
to update the listbox. Running this program will hang and nothing gets displayed in the listbox. If I limit the SendDlgItemMessage command to thread 0 I get the listbox to update and the program finishes quickly. All the documentation that I can find on OPENMP (online, in your help, and the 2 books I have)generally deals with print commands used with console windows. Is windows messaging limited to thread 0? Are there some examples of using OPENMP in a Windows program?

Any information will be greatly appreciated

Thanks
0 Kudos
3 Replies
IanH
Honored Contributor III
1,022 Views
I don't know the specifics of your program and to be honest my multithreaded Win32 programming experience is C++ based, but as a general principle (but not a rule), direct actions on a window should only be carried out by the thread that created the window. Beyond that, when SendMessage is called in say thread B to pass messages to a window that is owned by thread A, then thread B will have to wait around until thread A has the opportunity to process the message. If thread A is also part of your OMP team, I can quite easily imagine a dead-lock situation, where all the threads are sitting around waiting for each other.

If possible, consider having a dedicated GUI thread, that when required creates a worker thread (using CreateThread from the Intel fortran runtime) that then becomes the "master" of your OMP team. During the calculations the GUI thread just sits there monitoring the message queue for messages (like a GUI thread normally does). The various OMP threads then use SendMessage (or perhaps PostMessage which doesn't wait for the message to be processed before continuing) to send updates to the GUI. Be mindful about the lifetime of entities/objects that are passed through inter-thread messages - you don't want the storage for the msg variable to disappear before the listbox gets an opportunity to do its thing.

But perhaps you already have this setup, in which case, nothing to see here - move along...
0 Kudos
pbkenned1
Employee
1,022 Views

SendDlgItemMessage is identical to retrieving a handle to the specified control and calling the SendMessage function. However, neither of these functions return until the message has been processed, perhaps causing a deadlock in a multithreaded implementation.

Have you tried using SendMessageCallback or SendNotifyMessage functions instead? These send a message and return immediately.

To post a message to a thread's message queue and return immediately, use the PostMessage or PostThreadMessage functions.

Patrick Kennedy

Intel Developer Support

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,022 Views
I agree with IanH's recommendation.

Create an array of message pointers, one for each possible thread in your OpenMP system.
Add a cardnal thread number in thread local storage, preinitialized to -1.
Insert a parallel section near start and use InterlockedIncrement on a global variable (also initialized to -1), and use the after increment value to once only initialized the thread local storage cardnal thread number. Note, you do this because omp_get_thread_num() returns the current team member number (NOT cardinal thread number).
Whenever a thread has a new message to post, it simply writes the message pointer into the array at the index of its cardinal thread number. If these messages are allocated then the thread posting the message must not overwrite a prior message pointer (spin until the master thread is done with the message). The master thread periodically polls the table of messages, if pointer found, it copies and NULLs the pointer, then sends message to line of list box corisponding to index into pointer table, then the master thread deletest the message (when require to delete message).

While this does introduce a latency between insertion of message pointer and display, most applications will have a spot in the code where the master thread can poll list of messages without too much of a latency. Note, if your thread count is large and messages infrequent, you can have a global flag (adjacent to message pointer list) that gets set whenever a message pointeris written into the table. The master thread scan is made when this flag is set. Something like

do while(messageFlag)
messageFlag = .false.
do iMessage = 1,nThreads
if(associated(MessageTable(iMessage)) then
messageFlag = .true.
call YourDisplayMessage(iMessage, MessageTable(iMessage))
nullify(MessageTable(iMessage))
endif
end do
end do

Jim Dempsey
0 Kudos
Reply