No announcement yet.

Threads & Mutexs & Things

  • Filter
  • Time
  • Show
Clear All
new posts

  • Threads & Mutexs & Things

    I have created a small DLL that creats threads to do slow
    network tasks, however, I wanted to put a thread pool control
    into it e.g. I request 100 threads to run but only have 10
    at anyone time. So I did som'it like the following

    'Implement a currently running thread pool manager
    DO WHILE ThreadCnt > %MaxConcurrentThreads
    CALL SwitchToThread

    THREAD CREATE ThreadRoutine(pHeap) TO hThreadID
    IF hThreadID <> 0 THEN
    CALL WaitForSingleObject(ThreadCntMutex, 1000)' %INFINITE)
    INCR ThreadCnt
    CALL ReleaseMutex(ThreadCntMutex)
    END IF

    Then in the ThreadRoutine I have
    CALL WaitForSingleObject(ThreadCntMutex, %INFINITE)
    DECR ThreadCnt
    CALL ReleaseMutex(ThreadCntMutex)
    ExitThread 0

    The problem is that when it gets into the Do loop, the child threads
    don't appear to get a look in, hense, they can't do their bit
    and exit..........

    what am I missing ???


  • #2

    I haven't done this, I am just going from the win32 System
    Services manual.

    All threads can be given a priority using the SetThreadPriority API
    This means that you have complete control over the amount of processor
    time taken by your threads without having to write your own code.


    P.S. If you cannot find information about the SetThreadPriority API
    watch this space, I am sure you will get a few real gems on this
    thread in the not too distant future.



    • #3
      Thanks, but I didn't want to up the priority of child threads,
      I don't understand why the main thread isn't given control to
      it's child threads. I thought SwitchToThread did a simular thing
      as DoEvents does in VB.




      • #4
        VB's DoEvents basically just drops program control back to VB's hidden
        message pump, allowing Windows (and other) messages to be processed.
        It's not clear that your DLL provides any similar mechanism, in which
        case the program may be blocked waiting to process necessary messages.

        Tom Hanlin
        PowerBASIC Staff


        • #5
          What OS are you using (NT/4 Win2000/Pro) ?
          The SwitchToThread function causes the calling thread to yield execution to
          another thread that is ready to run on the current processor.
          The operating system selects the thread to yield to.
          The yield of execution is in effect for up to one thread-scheduling time slice.
          After that, the operating system reschedules execution for the yielding thread.
          The rescheduling is determined by the priority of the yielding thread and
          the status of other threads that are available to run.
          I am not sure that your 'DoThread' is able to do what you want it to
          I suppose processing of your threads will be lengthy,
          that is more than a few seconds...
          1) Create the thread-scheduler in its own thread.
             (this could be your main thread)
             In this thread create a invisible window (modal)
             make two 'functions' AddThread and RemoveThread
             AddThread will Resume The Thread(let it run and end) 
             RemoveThread will close the thread
             Use the DlgProc callback to 'remember' suspended threads
             waiting for execution
          2) Create your worker-thread in suspended mode
             call the "AddThread" function with ThreadId and
             let the Thread-Scheduler Resume execution 
             (according to your rules)
          3) When a worker-thread is ending, let it call
             RemoveThread to Close the Thread and activate a 
             suspended thread
          mailto:[email protected][email protected]</A>

          [This message has been edited by Fred Oxenby (edited January 09, 2001).]
          mailto:[email protected][email protected]</A>


          • #6

            Thanks for that, but I'm not sure I follow the advantage of
            creating a Window and usign DDT (this is because I have not used
            DDT before). Can you put a quick and dirty example together so
            that I can try to understand.




            • #7
              This is not working code, but tells you what I mean.
              Global ghWnd_Scheduler&
              Global Abort_Scheduler&
              Global gThread_Suspend&()
              Global gThread_Running&()
              %AddThread    = %WM_APP + 1
              %RemoveThread = %WM_APP + 2
              %FreeThreads  = %WM_APP + 3
              Function WindowThread(ByVal x&)As Long
              'create a modal scheduler-window
              Local WinCnt&
                Dialog New %HWND_DESKTOP,"",0,0,0,0 TO ghWnd_Sheduler&
                Dialog Show State ghWnd_Sheduler&,%SW_HIDE
                Dialog Show ModeLess ghWnd_Sheduler& Call DLGPROC_SCHEDULER
                 Dialog DoEvents To WinCnt&
                 If Abort_Scheduler <> 0 Then Dialog End ghWnd_Sheduler&
                Loop While WinCnt& > 0
              End Function                    
              CallBack Function DLGPROC_SCHEDULER
              Local Nr&,Nr1&,Rc&
                Select Case CBMsg
                  Case %WM_INITDIALOG
                   ReDim gThread_Suspended&(1 To 100)
                   ReDim gThread_Running&(1 To 10)
                  Case %AddThread
                   Array Scan gThread_Running(),= 0, To Nr&
                   If Nr& <> 0 Then 
                    gThread_Running&(Nr&) = CBwParam
                    Thread Resume CBwParam TO rc&
                    Array Scan gThread_Suspended&(),=0, To Nr&
                    If Nr& = 0 Then 'Fatal Error, more than 100 requests
                    gThread_Suspended&(Nr&) = CBwParam
                   End if 
                  Case %RemoveThread
                   Array Scan gThread_Running&(), =CBwParam, To Nr&
                   If Nr& = 0 Then 'Something is wrong here
                   Thread Close gTread_Running&(Nr&) To rc&
                   gThread_Running&(Nr&) = 0
                   Array Scan gThread_Suspended&(),<>0, To Nr1&
                   If Nr1& <> 0 Then
                    Swap gThread_Running&(Nr&), gThread_Suspended&(Nr1&)
                    Thread Resume gThread_Running&(Nr&) TO rc&
                   End if
                  Case %FreeThreads
                   Nr2& = 0
                   For Nr& = 1 to 100
                    If gThread_Suspended&(Nr&)=0 then incr Nr2&
                   Function = Nr&
                End Select   
              End Function
              '--When you create a new workerthread----------------
                Dialog Send ghWnd_Scheduler&,%FreeThread,0,0 To ThreadCnt&
                If ThreadCnt& > 0 then
                 Thread Create Worker(Parameter) Suspend To ThreadId&
                 If ThreadId& <> %NULL Then 
                  Dialog Send ghWnd_Scheduler&,%AddThread,ThreadId&,0
                 End If
                End If 
              '--In your worker thread, when it is about to end----
                Dialog Send ghWnd_Scheduler&,%RemoveThread,GetCurrentThreadId(),0
              You can add code for threads to query sceduler for abort if your
              app is terminating etc.

              mailto:[email protected][email protected]</A>

              [This message has been edited by Fred Oxenby (edited January 10, 2001).]
              mailto:[email protected][email protected]</A>