Announcement

Collapse
No announcement yet.

MultiThread Question

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Michael Mattias
    replied
    > That thread can then request more information from two other threads...

    "Threads" [of execution] do not maintain information. "Module" means "executable program file, either DLL or EXE."

    As far as handling a FIFO queue.. Ye Olde Anonymouse Pipe Demo seems fairly handy..

    Anonymous Pipe as Job Queue Demo 10-29-03

    ..but what may be handier is the "limit number of active threads using a semaphore" demo I have promised myself I will clean up and post this weekend. (It works great, but right now it's PB/CC only with output to the console. I want to add an 'activity' screen so both PB/CC and PB/WIN users can "plug and play" the same source code. It will also be a heck of lot easier to follow what's happening than trying to read the screen as it scrolls by)

    In this case, you could have a pipe server thread function accepting requests, and waiting for the first available "slot" of the "N" maximum simultaneous worker threads allowed. i.e, if you want to limit active wokder threads the, say, five, and have Windows manage the necessary 'suspend and resume' a semaphore object will be just what the doctor ordered for you.

    My demo would not serve this purpose, but in pseudo-code...

    Code:
    FUNCTION MAin() 
    
        DO 
             getInput 
             Write request to pipe. 
        LOOP UNTIL NO-MORE-INPUT
    
    THREAD FUNCTION PipeReader  () 
    
     DO 
          ReadPipe
          WaitOnSemaphore  ( slot available) 
          THREAD CREATE RealWork (app data from pipe)   
     LOOP 
    
    THREAD FUNCTION RealWork (app data from Pipe) 
        Yadda, yadda, yadda
        ReleaseSemaphore hSemaphone    ' make a slot available 
    END  FUNCTION
    Something like that, anyway.

    Optimization is different - it is perforce application specific. For me to comment on that I'd need documentation, source code and a purchase order.

    MCM
    Last edited by Michael Mattias; 24 Jul 2009, 02:18 PM.

    Leave a comment:


  • John Petty
    replied
    Originally posted by Michael Mattias View Post
    This I will call a 'meaningful omission' in the documentation for CONTROL GET TEXT.

    Besides, I got the text, didn't I? And subsequent users know now that CONTROL GET TEXT is NOT going to do the job for them?
    but it does work if you don't complicate the process.

    The "complexity" in that demo is almost one hundred percent the result of designing it to support an "abort" event.

    While polling a GLOBAL variable would "work", that option is not available if the thread function is located in a different code module. The demo as written would work just fine were the workher thread function lifted out and '#COMPILEd DLL' (You'd need a stub/wrapper function in the main module to serve as the object of the THREAD CREATE statement, since PB does not support THREAD CREATE with anything but the "user name" of the thread function. Eg, no such thing as 'THREAD CREATE DWORD functionaddress' although that would be pretty cool)
    Sorry don't understand, Globals work perfectly across INC files if that is what you mean by module. If you mean DLL's then the Global of that DLL is simply set with another exported function.
    More on
    externally changing the data in an executing TOE is IMO totally silly. A well-designed application would simply launch a fresh TOE using the new parameters
    Actually I have a major program that at start up starts 3 more threads, none of which ends until the program ends. Without going into details the main program responds to a KeyDown message sent from a VB DLL. If my program wants to use the information available from the VB DLL it passes the information to a FIFO queue of a thread to process. That thread can then request more information from two other threads (different internet sources) adding it to their FIFO work queues which don't try for out of time or redundent info. Both of these threads when getting info add it back to the the queue of the info processing thread.
    I haven't been able to work out a way that each of peices of data should be able to be handled by use once threads and be able to review and optimise their work queues.
    I know you could tell me a way . Of course they rely on mutexes not messages.
    John
    Last edited by John Petty; 24 Jul 2009, 01:09 PM.

    Leave a comment:


  • Michael Mattias
    replied
    comments in your demo complaining about documentation note you were not able to get the filespecs with a simple Control Get Text,
    This I will call a 'meaningful omission' in the documentation for CONTROL GET TEXT.

    Besides, I got the text, didn't I? And subsequent users know now that CONTROL GET TEXT is NOT going to do the job for them?

    The "complexity" in that demo is almost one hundred percent the result of designing it to support an "abort" event.

    While polling a GLOBAL variable would "work", that option is not available if the thread function is located in a different code module. The demo as written would work just fine were the workher thread function lifted out and '#COMPILEd DLL' (You'd need a stub/wrapper function in the main module to serve as the object of the THREAD CREATE statement, since PB does not support THREAD CREATE with anything but the "user name" of the thread function. Eg, no such thing as 'THREAD CREATE DWORD functionaddress' although that would be pretty cool)



    See also:
    Terminate Worker Threads Using Windows Events (and Using Thread Local Storage) Demo Dec 23 2005
    Last edited by Michael Mattias; 24 Jul 2009, 12:18 PM.

    Leave a comment:


  • John Petty
    replied
    MCM
    Sorry didn't mean to imply your demo used a mutex it uses a more complicated WaitForSingle for the abort when simply setting a global long flag would do the job.
    However, in the (correct) demo the primary thread is suspended only when the worker thread of execution is first launched, and suspended only until the thread function has copied its parameters to a LOCAL variable, safe from change by anything occurring in another TOE. It is never suspended after that.
    Not quite as the comments in your demo complaining about documentation note you were not able to get the filespecs with a simple Control Get Text, my suggestions solve that.
    However, even though 'complex' is a little off topic for this [forum] thread, externally changing the data in an executing TOE is IMO totally silly. A well-designed application would simply launch a fresh TOE using the new parameters.
    In most cases I would agree, was just expanding the options.

    Leave a comment:


  • Michael Mattias
    replied
    which removes the problem of the DDT main being stalled .......as the Dialog is not stalled in a waitfor statement ... can be done with a few simple Windows messages, no Mutexes ...
    There is no mutex object used in the linked demo, so I'm not sure you have reviewed the correct example.

    However, in the (correct) demo the primary thread is suspended only when the worker thread of execution is first launched, and suspended only until the thread function has copied its parameters to a LOCAL variable, safe from change by anything occurring in another TOE. It is never suspended after that.

    Take a more complex situation where you might wish to keep the thread alive but give it new data.
    "Complex" is something I try to avoid in my demos. This is by design.

    However, even though 'complex' is a little off topic for this [forum] thread, externally changing the data in an executing TOE is IMO totally silly. A well-designed application would simply launch a fresh TOE using the new parameters.

    Perhaps everyone's interests would be best served by you posting demos of your suggested techniques. Why don't you post that (those?) as replies to my demo; that will make it easy for users to 'pick and choose.'

    MCM

    Leave a comment:


  • John Petty
    replied
    Originally posted by Michael Mattias;319526Here is a demo you should review:
    [url=http://www.powerbasic.com/support/pbforums/showthread.php?t=35619
    GUI + Worker Thread + Abort Demo 11-24-07[/url]

    I think it is a terrific demo of the Right Way to handle a user interface plus worker threads. However, I am not exactly a neutral party.

    MCM
    MCM
    Yes it is a good example but I think it is overly complex for what it is trying to do (particularly with a couple of GLOBALS).
    All the steps you show can be done with a few simple Windows messages, no Mutexes and no WaitForSingleObject. It can be all done with a few User messages which removes the problem of the DDT main being stalled while waiting or horrendously slow if polling. To take your example.
    The user types in the file name/details and clicks %ID_Start the first action for this is to make the input textbox read only, Second it does Thread Create, then Thread Close.
    The thread can then get the details with a simple Control Get Text as the Dialog is not stalled in a waitfor statement.
    The thread can then update the Dialog with simple Control Set Text or update a progress bar etc.
    Abort, well thats a simple matter of setting a flag in a Global Long which is checked by the thread whenever, no need for Mutex's etc as a simple long read is an Atomic instruction.
    Last instruction of the thread before END FUNCTION is Dialog Post a user message indicating thread ended and the whole process can be run again.
    Take a more complex situation where you might wish to keep the thread alive but give it new data. Again easy but this time the thread uses Dialog Send a user message saying give me new info. The thread is then suspended until the Dialog returns from that message, simple synchronisation.
    John

    Leave a comment:


  • Michael Mattias
    replied
    >I think the reason for modeless is because it is running in higher priority

    Modal/Modeless is programmer decision and is not tied to thread priority at all.

    MCM

    Leave a comment:


  • Miguel Pando
    replied
    Sorry I forgot to mention, main thread is a modeless window.
    I think the reason for modeless is because it is running in higher priority.
    Code:
        DIALOG SHOW MODELESS hDlg, Call xDialog TO x
        Do
           WaitMessage
           DIALOG DOEVENTS
           IF quitflag THEN EXIT DO
        LOOP
    '***************************************************************
    FUNCTION thread_run(BYVAL i AS LONG) AS LONG
    '***************************************************************
        DO
            'Code here
            'Code here
            SendMessage hDlg, %THREAD_SUSPEND, 0, i
        LOOP
    END FUNCTION
    Worker threads sendmessage to Main thread Window.

    Thank you

    Leave a comment:


  • Michael Mattias
    replied
    But to answer yoiur question directly, if you are using DDT to create your windows, just use the DDT message loop in your primary Thread of Execution (the one in which your create your windows) . Don't insert WaitMessage... let the compiler generate the optimal code for message processing. I dare suggest the folks in Florida have given this a bit more thought than have you.

    MCM

    Leave a comment:


  • Michael Mattias
    replied
    >Main thread in higher
    >priority receiving messages from worker threads(Sendmessage to Main thread).

    Messages are not sent to threads. Messages are sent to windows.

    You do not need a message loop (DIALOG DOEVENTS) in any thread except threads which create windows (DIALOG NEW/SHOW); you will generallly only create windows in one (1) thread of your application... your extra threads of execution will be 'background' or "batch" tasks started based on what the user does.

    Here is a demo you should review:
    GUI + Worker Thread + Abort Demo 11-24-07

    I think it is a terrific demo of the Right Way to handle a user interface plus worker threads. However, I am not exactly a neutral party.

    MCM

    Leave a comment:


  • Miguel Pando
    started a topic MultiThread Question

    MultiThread Question

    Hello

    In a program with many worker threads running, one Main thread in higher
    priority receiving messages from worker threads(Sendmessage to Main thread).
    Code:
    'Is this a better procedure
    Do
      WaitMessage
      Dialog Doevents               'User Input
      if quitflag then exit do
    Loop
    'Than this
    Do
      x=PeekMessage(msg, hDlg, 0, 0, 0)     'No Remove
      if x then
            Dialog Doevents
      else
            Sleep w           'w computed based on number of worker threads
      end if
      if quitflag then exit do
    Loop
    Did not know much about WaitMessage.

    Thanks
Working...
X