Hi Guys
I know thread issues are being around for sometime but i´m struggling to understand completely. I´m trying to create a app that opens a imagee (with freeimage libraries) and display them on the proper screen (A client area). The problem relies that immediately after the image is loaded it needs to perform some checks for analyzing if the image is compressed or the levels of blur it may have etc. For that purpose, since it is heavy computation i putted the opening routine inside a thread using beginthreadex in msvcrt.
The problem is how i can be sure that the routines are finished before passing the rest of the functions ? I create it is something like this:
Main messages of the workspace where the image is loaded
Proc MainProc:
Arguments @hWnd, @uMsg, @wParam, @lParam
.......
...Else_If D@uMsg = &WM_COMMAND
call On_WmCommand D@hWnd, D@uMsg, D@wParam, D@lParam
xor eax eax
.......
...Else_If D@uMsg = &WM_PAINT
......
etc etc etc
On_Wm_Command function is where the main thread is called like this:
Proc On_WmCommand:
Arguments @hWnd, @uMsg, @wParam, @lParam
Local @Count
...If D@wParam = M00_Open ; Open file from the menu
.............do some stuff, open image, put messagebox alerts in case of failure, etc
C_call 'msvcrt._beginthreadex' &NULL, 0, OpenImageThread, &NULL, &THREAD_PRIORITY_NORMAL, OpenImgThreadId ; <----------------The main thread function
mov ebx eax
mov D$ButtonStatus 1
;call 'kernel32.WaitForSingleObject' ebx, &INFINITE <---------------------- Why ????????? I removed this because the function never ends, and enter on a infinite loop here never exiting the thread
If ebx = &NULL
call ReportWinError {'Debugger: CreateThread (Resource Manager)' 0}
Else
; we don't need the thread handle
call 'Kernel32.CloseHandle' ebx
End_If
xor eax eax
...End_If
The main thread function:
Proc OpenImageThread:
Arguments @lpData
; Check for status of the menu, see if it is needed to use grayscale and so on
; access InvalidateRect, EnableWindow, Loadcursor and other windows apis on the main handle of the workspace and also on the handle of the main window.
call DetectImageBlur ;<----- The main function responsible for checking if the image is blurred, and the compression it have. Also, this function places the proper messages with sprintf on the statusbar of the window, set new cursor etc.
C_call 'msvcrt._endthreadex' 0 ; <---- End the thread
mov D$ButtonStatus 0
xor eax eax
EndP
So...is it the proper way to calling and ending the thread ? How can i make sure that once i opened a file and triggered the WM_COMMAND messages, the main routine OpenImageThread used in beginthreadex is fully and properly loaded before the program proceeds to the rest of the functions enabling menus only after the main routine is fully loaded etc etc ?
I tried to use CreateThread but i have the same questions and after reading somewhere that is better using beginthreadex for safety problems i decided to use it instead CreateThread.
do a google search for 'CreateMutex' or 'Mutex Objects', I think that is what you are looking for.
Quote
You can use a mutex object to protect a shared resource from simultaneous access by multiple threads or processes
does that fit the bill?
There are others that also do similar to 'wait' until one process is finished before resuming another. You'll have to do a search as my memory is a little fuzzy.
'CreateSemaphore' ---
Quote
Using Semaphore Objects (Windows) - msdn.microsoft.com
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686946 (https://msdn.microsoft.com/en-us/library/windows/desktop/ms686946)...
The following example uses a semaphore object to limit the number of threads that can perform a particular task. First, it uses the CreateSemaphore function to create the semaphore and to specify initial and maximum counts, then it uses the CreateThread function to create the threads. Before a ...
hope this little bit of info helps
You start the thread, and once it is ready, the thread sends a private (->RegisterWindowMessage) message to the main window:
Case MyPrivateMessage
Print "Great, now I can enable my menus!"
Hi guys
Zed, i read it, but still confused :(
JJ, i tried the RegisterWindowMessage, but on M$ docs it says that it maybe better using WM_USER. I tried both cases and nothing happened. I then tried to put a dummy flag inside the thread and just after it, enabled a TRUE fglag to check either the thread ended or not...but...nothing..:(
I´m doing something like this:
mov D$DummyVar 1 ; Just a dummy var to see if the thread ended or not. In case, 1 means thread running
C_call 'msvcrt._beginthreadex' &NULL, 0, OpenImageThread, &NULL, &THREAD_PRIORITY_NORMAL, OpenImgThreadId
mov ebx eax
If D$DummyVar = 0 ; If thread ended enable menus
call Enablemenu ...............................
End_If
Inside the thread it have:
Proc OpenImageThread:
Arguments @lpData
....
mov D$DummyVar 0 ; <---- Stteled the flag to 0 to say when the thread really ended...but..nothing is happenning :(
C_call 'msvcrt._endthreadex' 0
xor eax eax
EndP
The problem is that when the app starts, it goes to beginthreadex' and continues ....pass through DummyVar (jumping it, because the flag is still 1....and only later, it enter inside the thread function at OpenImageThread....but....it does not return and therefore, the next line of code that check for the DummyVar is not reached.
If i use the "call 'kernel32.WaitForSingleObject' ebx, &INFINITE" then the things got worst.
I´m really having troubles to understand how this whole thread thing works. Someone have examples of using this on a way that the app must check either the thread is fully ended or not ? (I mean, without the problem that it enter on a infinite loop) Examples using waitformultipleobjects, waitforsingleobjects, createthread, beginthreadex, createmutex etc etc ?
Simple demo below. Just run the exe to see the logic.
GuiParas equ "Thread demo", x950, y20, w160, h120, cblack, b00FFFFD0h
include \masm32\MasmBasic\Res\MbGui.asm
usedeb=1
push eax
invoke CreateThread, 0, 0, MyThreadProc, 111, 0, esp
pop edx
deb 4, "CT: handle, ID", eax, edx
Event Message
inc msgCount
deb 4, "msg", chg:msgCount ; , wParam, _lParam ; see deb
.if uMsg==WM_USER+123
Print Str$("******** WM_USER arrived, wParam=%i", wParam_), Str$(", lParam=%i ********\n", lParam_)
MsgBox 0, "The thread ended, it seems", "Hi", MB_OK
mov eax, 123456789 ; retval for SendMessage
jmp @RetEax
.endif
EndOfEvents
MyThreadProc:
push ebx
xor ebx, ebx
.Repeat
invoke Sleep, 100
Print "*"
inc ebx
.Until ebx>=30
PrintLine " bye"
pop ebx
invoke SendMessage, hGui, WM_USER+123, 456, 789
deb 4, "SendMessage WM_USER+123 retval", eax, $Err$()
retn 4
GuiEnd
And you always should ask yourself what you will gain by running some code in a separate thread.
In your case, if you must complete that "heavy computation" before continuing with the main program, why put it in a separate thread? What will the remainder of your program do during that "heavy computation" in a separate thread?
How much computer time do you expect to save?
How much less code will you have to write?
Unless you are primarily experimenting with the use of threads for possible future use.... :dazzled:
Hi JJ. Many thanks...:)
I forgot to put the WM_USER indeed (Itr can be retrieved also with postmessage ?). But, what about the closethread ?
On your example you created the thread but when for correctly ending the thread with "ExitThread" or "endthreadex" inside the thread function "MyThreadProc" in your case or it can be placed somewhere else ? Also, on your example you used the value 111 as the thread parameter. This value is returned only after the thread is ended or it is reached without the thread ends (at pop edx, for example) ?
Hi Raymond, i have some difficulties in understanding the thread functionality in general usage. But, on this case, specifically is for trying to make some functions/algorithms i´m using works a bit faster without "hanging' the whole app waiting to the function ends. I´m making some tests on algorithms related to image managment, such as a super resolution algorithm, blur detection and jpeg artifact detector that makes heavy usage in computation for large images (Well...not that large, but, it takes some few secs to finish the work). I´m currently analyzing the functionality of these algorithms in order to try porting them to video (and not only images). Waiting 1 or 2 seconds is ok when it concerns only images, but for using on video it is aa different story because it needs to be faster then that, specially considering that a video can have 100.000 frames or something, so the faster the algorithms goes (without hanging the rest of the application that uses the algo) the better will be.
So, perhaps the best way is using threads to allow the rest of the application free to is being used while these functions/algorithms are being performed. Eventually, if i succeed to finish these algorithms i´ll give a test on a plugin for virtualdub and see how it works on video processing as well but, before that i need to understand these threads functionality completely
Ah! This is about image processing and possible video processing? Post a new topic perhaps, with image and/or video processing in the title. Maybe there are some members who have the solution for your problem. As Raymond suggested, it might not be necessary to having a separate thread running -- perhaps a better processing algorithm?
Quote from: guga on July 13, 2018, 01:52:12 AMyou created the thread but when for correctly ending the thread with "ExitThread" or "endthreadex" inside the thread function "MyThreadProc" in your case or it can be placed somewhere else ? Also, on your example you used the value 111 as the thread parameter. This value is returned only after the thread is ended
From the old Win32.hlp:
QuoteExitThread is the preferred method of exiting a thread. When this function is called (either explicitly or by returning from a thread procedure), the current thread's stack is deallocated and the thread terminates
The 111 is given
to the thread for its own use. Try this:
invoke CreateThread, 0, 0, MyThreadProc, 22, 0, esp
...
.Until ebx>=[esp+8]
You may return something in eax, and retrieve that value with GetExitCodeThread, but its rather useless in this case because your WM_USER+x message gives you already wParam and lParam.
You may return something in eax, and retrieve that value with GetExitCodeThread, but its rather useless in this case because your WM_USER+x message gives you already wParam and lParam.
Ohn, i see. So, on this particular case i´ll use WM_USEr with sendmessage/postmessage instead. I´ll continue studying this thread functions for further usage. Eventually i´ll be forced to use some of these. I never used those before on a regular daily basis. Although these functions exists in RosAsm (For the debugger mainly), those routines were written by a collaborator at the time (Ludwig) and i didn´t have enough time to analyse all of those functions yet. I´ll probably have to understand it better, because i´ll restart working on RosAsm development as soon as possible.
QuotePost a new topic perhaps, with image and/or video processing in the title
Hi Zed. Yes, i´m seeing how this works now for image processing algorithm. I´m reading the new algorithm from google RAISR at https://www.pcmag.com/news/351027/google-raisr-intelligently-makes-low-res-images-high-quality and it is really promissing. I found some information on github but it is in python :(
https://github.com/movehand/raisr
https://github.com/volvet/RAISR-1
https://github.com/MKFMIKU/RAISR
Once i finish these routines i´m building i´ll post it here and open a new thread related to image/video processing. The routines i´m trying to create are not related to this RAISR, but i´m trying to go slowly, learning what i can before (who knows :icon_mrgreen: :icon_mrgreen:) give a try eventually on this new google work.
The idea behind this RAISR is amazing. :eusa_clap: :eusa_clap: :eusa_clap:
Reading google paper "RAISR: Rapid and Accurate Image Super Resolution" is a hard task for me to understand, but, one thing i though that can be implemented is the structure preservation using census transformation (example here: https://hangyinuml.wordpress.com/2012/09/08/census-transform-c-implementation). It takes onto account the position of the pixels related to each other rather then the chromacity or saturation, etc. Since it is blind to luma, it preserves the original structure of a given image, which can be useful for functions related to motion estimation, rotation, object extraction etc etc. Later i´ll open a specific thread for all of this :) It is really amazing.
Quote from: guga on July 13, 2018, 05:28:02 AMi´ll use WM_USEr with sendmessage/postmessage
I would suggest SendMessage: In your WM_USER handler, the thread and its variables are still alive (e.g. an open file), so you can do some processing. With PostMessage, you can't be sure about the thread's state because it returns immediately.