Announcement

Collapse
No announcement yet.

looking for simple "thread create..." example

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

  • looking for simple "thread create..." example

    hello.

    1) I am looking for a simple "thread / thread create" example to learn more about this sub/functions relationship. It seems I am too silly to use the search forum for these words, sorry. I've got several pages about that topic.

    2) I've found this example from help file. Perhaps anybody can help to fix this thread example so I will be glad

    Code:
    #COMPILE EXE
    #DIM ALL
    
    #INCLUDE "win32api.inc"
    
    
    FUNCTION PBMAIN () AS LONG
    'MSGBOX "hello my dear thread: " + STR$(myThread(1))
    
    END FUNCTION
    
    SUB SpawnThreads()
    
      LOCAL x AS LONG
      LOCAL s AS LONG
      DIM hThread(10) AS LOCAL DWORD
    
      FOR x = 1 TO 10
        THREAD CREATE MyThread(x) TO hThread(x)
        SLEEP 50
      NEXT
    
      MSGBOX "10 Threads Started! " + _
                 "Wait for them to finish!"
    
      DO
        FOR x = 1 TO 10
          SLEEP 0
          THREAD STATUS hThread(x) TO s
          IF s <> &H103 AND s <> 0 THEN ITERATE DO
        NEXT
      LOOP WHILE s
    
      FOR x = 1 TO 10
    
        THREAD CLOSE hThread(x) TO s
    
      NEXT x
      MSGBOX "Finished!"
    
    END SUB
    
    
    
    ' The following is executed as a thread Function!
    THREAD FUNCTION MyThread (BYVAL x AS LONG) AS LONG
    
      LOCAL n AS LONG
      LOCAL t AS SINGLE
    
      MSGBOX "Begin Thread" + STR$(x)
      t = TIMER
    
      FOR n = 1 TO 10
        SLEEP 100 + 100 * x
      NEXT n
    
      t = TIMER - t
      MSGBOX "End Thread" + STR$(x) + _
        " Elapsed time = " + STR$(t,5)
    
    END FUNCTION
    3) what's the mainly purpose or benefit of using "threads"?

    thanks, best regards, frank

  • #2
    1) test-thread.bas :

    Code:
    #COMPILE EXE
    #DIM ALL
    #INCLUDE "testneu.inc"
    
    FUNCTION PBMAIN () AS LONG
    
      MSGBOX "test dialog + inc file", %MB_OK, "test me :) " & STR$(test_me(1,"yes", "yes",1,1) )
    
    END FUNCTION
    2) include file: "testneu.inc"

    Code:
    #IF NOT %DEF(%TESTNEU_INC)
    #ENDIF
    
    %Testneu_INC = 10000
    %buttonx = 10001
    %buttonClose = 10002
    
    FUNCTION Test(BYVAL dummyex AS LONG) AS LONG
          LOCAL hDlg AS DWORD
          DIM result AS LONG
    
          DIALOG NEW 0, "simple Test Dialog",100,100,220,205, %WS_POPUP OR %WS_SYSMENU OR %WS_OVERLAPPEDWINDOW OR %WS_MINIMIZEBOX,0 TO hDlg
          DIALOG SET COLOR hdlg, -1, RGB(10,200,255)
          CONTROL ADD BUTTON, hDlg, %buttonx, "obelix", 25, 25, 50, 30
          CONTROL ADD BUTTON, hDlg, %buttonClose, "close", 25, 85, 50, 30
          DIALOG SHOW MODAL hDlg CALL DlgProc TO result
       END FUNCTION
    
    FUNCTION Test_me(BYVAL hParent AS LONG, BYVAL sText AS STRING, BYVAL sTitle AS STRING, BYVAL x AS LONG, BYVAL y AS LONG) AS LONG
        LOCAL h AS LONG
        LOCAL r AS DWORD
        THREAD CREATE Test(0) TO h
        THREAD CLOSE h TO r
    
    END FUNCTION
    
    CALLBACK FUNCTION DlgProc() AS LONG
          SELECT CASE CBMSG
        CASE %WM_COMMAND
          IF CBWPARAM = %ButtonClose THEN DIALOG END CBHNDL,0
        END SELECT
    
    END FUNCTION
    well, but I would like to understand what's the job of threads another simple example could help.

    servus, bye, frank

    Comment


    • #3
      Try this short example from gbSnippets (there's another 5 thread examples online at http://www.garybeene.com/power/code).

      The example doesn't do much, but serves to show the basic elements of creating a thread.
      Code:
      'Compilable Example:
      #Compile Exe
      #Dim All
      #Include "Win32API.inc"
      Global hDlg as DWord, hThread as DWord
      Global iCountA&, iCountB&
      Function PBMain() As Long
         Dialog New Pixels, 0, "Test Code",300,300,200,200, %WS_OverlappedWindow To hDlg
         Control Add Button, hDlg, 100,"Start Thread", 50,10,100,20
         Control Add Label, hDlg, 200,"<main thread count>", 50,40,100,20
         Control Add Label, hDlg, 300,"<extra thread count>", 50,70,100,20
         Dialog Show Modal hDlg Call DlgProc
      End Function
      
      CallBack Function DlgProc() As Long
         If CB.Msg = %WM_Command AND CB.Ctl = 100 AND CB.Ctlmsg = %BN_Clicked Then
           Thread Create NewThread(0) To hThread       'start the new thread, argument not used
            Thread Close hThread To hThread    'suggested by PowerBASIC Inc. as good practice
            MainThread    'in the main thread, keep doing something
            Control Set Text hDlg, 200, "Main" + Str$(iCountA&)
            Control Set Text hDlg, 300, "Not-Main" + Str$(iCountB&)
         End If
      End Function
      
      Function MainThread () As Long
           Do
              Incr iCountA&
           Loop Until iCountA& > 20000000
      End Function 
      
      Thread Function NewThread (ByVal x As Long) As Long
           Do
              Incr iCountB&
           Loop Until iCountB& > 2000
      End Function
      Last edited by Gary Beene; 12 Aug 2010, 02:41 PM.

      Comment


      • #5
        One of the better features for threads is imo the preventing of exitting the application while threads are still running.
        See this simple but good code:

        Code:
        Do
                Sleep 100
        Loop While ThreadCount > 1
        I have a thread example here for you:
        http://www.powerbasic.com/support/pb...ad.php?t=44006
        hellobasic

        Comment


        • #6
          Threadcount never worked well for me. I usually ended up using some type of wait function and/or a Semaphore.
          sigpic
          Mobile Solutions
          Sys Analyst and Development

          Comment


          • #7
            i was playing around with controlling a fax printer dialog and created a thread sort of like this below, i changed the fax printer driver to a cutepdf printer driver for demonstrating the use of a thread that i was using.

            Never got it to fully work because of my simple windows programming skills.

            But this creates a thread anyway and i am not really sure if this is the way to do it, but it seems to work.

            if this example seems stupid to most people for me to post this, i am ok with that.

            Code:
            #COMPILE EXE
            #DIM ALL
            #INCLUDE "win32api.inc"
            GLOBAL ithreadclosed AS LONG
            
            
            THREAD FUNCTION cutepdf(BYVAL x AS DWORD) AS LONG
            'the possible code in this function could of actually found the cutepdf writer "Save As" dialog and
            ' sent keys strokes to it in order dialog to save the printout to a pdf
            
            'but i just incremented the long variable I upto 100 and display it using msgbox
            
            SLEEP 200
            
                LOCAL I AS LONG
                DO
                I=I+1
                SLEEP 50
                IF I=100 THEN
                    MSGBOX "I="+STR$(I)
                    EXIT DO
                END IF
                LOOP
               ithreadclosed=1
            END FUNCTION
            
            FUNCTION PBMAIN
            
                LOCAL x AS LONG
                LOCAL hthread AS DWORD
            
                THREAD CREATE cutepdf(x) TO hthread
                SLEEP 500
                XPRINT ATTACH "CutePdf Writer", "My auto pdf"
                DIM i AS LONG
                XPRINT "Hello Gang"
                XPRINT CLOSE
            
                 DO
                 IF ithreadclosed=1 THEN EXIT DO
                 SLEEP 300
                 LOOP
                 THREAD CLOSE hthread TO x
                  'maybe a short sleep state here would be good, i do not know but it sounds like i know what i am doing
                 SLEEP 500
            END FUNCTION
            Last edited by Paul Purvis; 13 Aug 2010, 01:26 AM.
            p purvis

            Comment


            • #8
              thanks all (michael, paul, roger, gary, edwin) for hints, advices and examples

              my first attempt with thread example above is missing only the line

              Code:
              spawnThreads
              this example works very well for me and I can see how threads are working. I am not sure if I am using threads, but I will see in future.

              Code:
              #COMPILE EXE
              #DIM ALL
              
              #INCLUDE "win32api.inc"
              
              FUNCTION PBMAIN () AS LONG
               spawnThreads
              END FUNCTION
              
              SUB SpawnThreads()
              
                LOCAL x AS LONG
                LOCAL s AS LONG
                DIM hThread(10) AS LOCAL DWORD
              
                FOR x = 1 TO 10
                  THREAD CREATE MyThread(x) TO hThread(x)
                  SLEEP 50
                NEXT
              
                MSGBOX "10 Threads Started! " + _
                           "Wait for them to finish!"
              
                DO
                  FOR x = 1 TO 10
                    SLEEP 0
                    THREAD STATUS hThread(x) TO s
                    IF s <> &H103 AND s <> 0 THEN ITERATE DO
                  NEXT
                LOOP WHILE s
              
                FOR x = 1 TO 10
              
                  THREAD CLOSE hThread(x) TO s
              
                NEXT x
                MSGBOX "Finished!"
              END SUB
              
              ' The following is executed as a thread Function!
              THREAD FUNCTION MyThread (BYVAL x AS LONG) AS LONG
              
                LOCAL n AS LONG
                LOCAL t AS SINGLE
              
                MSGBOX "Begin Thread" + STR$(x)
                t = TIMER
              
                FOR n = 1 TO 10
                  SLEEP 100 + 100 * x
                NEXT n
              
                t = TIMER - t
                MSGBOX "End Thread" + STR$(x) + _
                  " Elapsed time = " + STR$(t,5)
              
              END FUNCTION
              more to come with new example if I know more about "thread" topic
              I've tested already nearly 75 per Cent of the linked examples.

              thanks, best regards, frank

              Comment


              • #9
                Frank,
                what's the mainly purpose or benefit of using "threads"?
                The obvious uses are to allow your program to:
                1) continue doing useful work while also waiting for something
                2) efficiently manage resources
                3) make use of multiple cores/CPUs

                In case 1) you might have a job which is taking a long time but isn't using a lot of resources, such as waiting for a disk operation or waiting for a key to be pressed. It might be useful to continue doing something else while waiting, you can create a thread which does the waiting so only that one thread then waits and the main code or another thread can continue running.

                Here's an example. The speech interface blocks the current thread while speaking. If the speech is done in it's own thread then you don't have to wait for the speech to finish in order to do something else:

                Code:
                'PBWin9/PBCC5 program
                #COMPILE EXE
                #DIM ALL
                
                FUNCTION PBMAIN () AS LONG
                LOCAL k AS STRING
                LOCAL hWin AS LONG
                
                GRAPHIC WINDOW "Threads",10,10,400,400 TO hWin
                GRAPHIC ATTACH hWin,0
                
                sayit("See how the graphics continue to run while the talking is done in a thread. Press a key to see the same without using threads.")
                
                DO
                    GRAPHIC LINE (RND(1,400),RND(1,400))-(RND(1,400),RND(1,400)),RND(0,&h00ffffff)
                    GRAPHIC INKEY$ TO k
                LOOP UNTIL k<>""
                
                
                sayit2("Now the graphics stop until the talking is finished because no thread is used.")
                
                DO
                    GRAPHIC LINE (RND(1,400),RND(1,400))-(RND(1,400),RND(1,400)),RND(0,&h00ffffff)
                    GRAPHIC INKEY$ TO k
                LOOP UNTIL k<>""
                
                
                GRAPHIC WINDOW END
                
                
                END FUNCTION
                
                
                FUNCTION sayit(WhatToSay AS STRING) AS LONG
                'the SayIt function was blocking the main code so call it in its own thread
                'it must be done via a static as the new thread may not get access to the string until
                ' after the string in changed by the main code.
                
                STATIC ThingToSay AS STRING
                LOCAL hThread AS LONG
                    ThingToSay=WhatToSay
                
                    THREAD CREATE SayItThread(VARPTR(ThingToSay)) TO hThread
                    THREAD CLOSE hThread  TO hThread
                END FUNCTION
                
                
                
                
                FUNCTION SayItThread(BYVAL ThingToSay AS STRING PTR) AS LONG
                'say whatever is assigned to the the string pointed to by ThingToSay
                    LOCAL oSp AS DISPATCH
                
                    SET oSp = NEW DISPATCH IN "SAPI.SpVoice"
                    IF ISFALSE ISOBJECT(oSp) THEN EXIT FUNCTION
                
                    LOCAL vRes AS VARIANT
                    LOCAL vTxt AS VARIANT
                    LOCAL vTime AS VARIANT
                
                    LOCAL flags AS VARIANT
                
                    vTxt = @ThingToSay
                    OBJECT CALL oSp.Speak( vTxt,flags ) TO vRes
                
                    vTime = -1 AS LONG
                    OBJECT CALL oSp.WaitUntilDone(vTime) TO vRes
                
                
                IF ISTRUE ISOBJECT(oSp) THEN
                  SET oSp = NOTHING
                END IF
                
                END FUNCTION
                
                
                
                
                FUNCTION SayIt2(WhatToSay AS STRING) AS LONG
                'say whatever is assigned to the the string WhatToSay
                    LOCAL oSp AS DISPATCH
                    STATIC WhatToSayText AS STRING
                
                    WhatToSayText = WhatToSay
                
                    SET oSp = NEW DISPATCH IN "SAPI.SpVoice"
                    IF ISFALSE ISOBJECT(oSp) THEN EXIT FUNCTION
                
                    LOCAL vRes AS VARIANT
                    LOCAL vTxt AS VARIANT
                    LOCAL vTime AS VARIANT
                
                    LOCAL flags AS VARIANT
                
                    vTxt = WhatToSay
                    OBJECT CALL oSp.Speak( vTxt,flags ) TO vRes
                
                    vTime = -1 AS LONG
                    OBJECT CALL oSp.WaitUntilDone(vTime) TO vRes
                
                
                IF ISTRUE ISOBJECT(oSp) THEN
                  SET oSp = NOTHING
                END IF
                
                END FUNCTION
                Paul.

                Comment


                • #10
                  Frank,
                  for case 3)
                  Try running the following. It calculates stuff with and without threads to show how to use multiple cores. You'll need to can more than 1 core/CPU on your computer to notice anything.
                  Try running it with Task Manger open showing the CPU usage.

                  Code:
                  'PBWin9/PBCC5 program
                  'see if I can operate on data in an array using threads so a multi-core CPU will complete faster
                  
                  %LoopLimit = 2000
                  
                  #COMPILE EXE
                  #DIM ALL
                  
                  #INCLUDE "win32api.inc"
                  
                  TYPE ThreadToken
                      StartIndex   AS LONG
                      EndIndex     AS LONG
                  END TYPE
                  
                  
                  GLOBAL a() AS QUAD
                  
                  
                  FUNCTION PBMAIN () AS LONG
                  LOCAL r,t,ASize, NoofThreads,hWin AS LONG
                  LOCAL t1,t2 AS EXT
                  LOCAL freq, count0, count1 AS QUAD
                  
                  GRAPHIC WINDOW "Thread tests",10,10,400,400 TO hWin
                  
                  GRAPHIC ATTACH hWin,0
                  
                  GRAPHIC PRINT "Running..."
                  
                  QueryPerformanceFrequency freq   'Get timer frequency.
                  
                  aSize = 362880 ' a number divisible by all integers up to 10 so I don't get odd elements when I split the array
                  DIM a(aSize) AS QUAD 'LONG
                  
                  'fill array with test data
                  FOR r = 1 TO aSize
                      a(r)=r
                  NEXT
                  
                  
                  QueryPerformanceCounter count0   'read the timer at the start of the test
                  
                  'the job to do without threads
                  FOR t = 1 TO %LoopLimit
                      FOR r = 1 TO aSize
                          a(r)=a(r)+1
                      NEXT
                  NEXT
                  
                  
                  QueryPerformanceCounter count1   'read the timer at the end of the test
                  
                  'check to make sure the answer is correct
                  FOR r = 1 TO aSize
                      IF a(r)<> r+ 1 * %LoopLimit THEN
                          GRAPHIC PRINT "error at location";r;a(r)
                      END IF
                  
                  NEXT
                  
                  GRAPHIC PRINT "Time without threads=";FORMAT$(1000*(count1-count0)/freq,"######0.000");"msec"  'print the elapsed time
                  
                  
                  
                  'now do the same job with threads
                  LOCAL Token() AS ThreadToken
                  LOCAL hThreads() AS LONG
                  LOCAL junk AS LONG
                  
                  DIM hThreads(1 TO 20)
                  DIM Token(1 TO 20)
                  
                  FOR NoofThreads = 1 TO 10
                  
                      'fill array with the same test data
                      FOR r = 1 TO aSize
                          a(r)=r
                      NEXT
                  
                      QueryPerformanceCounter count0   'read the timer at the start of the test
                      FOR r = 1 TO noofThreads
                  
                          Token(r).StartIndex= 1+ (r-1)*(ASize/NoofThreads)
                          Token(r).EndIndex=  r*(ASize/NoofThreads)
                  
                          THREAD CREATE ProcessingThread(VARPTR(Token(r))), TO hThreads(r)
                          THREAD SET PRIORITY hThreads(r), %THREAD_PRIORITY_BELOW_NORMAL
                  
                      NEXT
                  
                  
                      FOR r = 1 TO NoofThreads
                          WaitForSingleObject(hThreads(r), BYVAL %INFINITE)
                      NEXT
                  
                      FOR r = 1 TO noofThreads
                          THREAD CLOSE hThreads(r) TO junk
                      NEXT
                  
                      QueryPerformanceCounter count1   'read the timer at the end of the test
                  
                      'check to make sure the answer is correct
                      FOR r = 1 TO aSize
                          IF a(r)<> r + 1* %LoopLimit THEN
                              GRAPHIC PRINT "error at location";r;a(r) ;" Threads=";noofThreads
                              GRAPHIC WAITKEY$
                          END IF
                  
                      NEXT
                      GRAPHIC PRINT "Time taken with";NoofThreads; "threads="FORMAT$(1000*(count1-count0)/freq,"######0.000");"msec"  'print the elapsed time
                  
                  NEXT
                  
                  
                  GRAPHIC PRINT "Done."
                  GRAPHIC WAITKEY$
                  GRAPHIC WINDOW END
                  
                  END FUNCTION
                  
                  
                  
                  THREAD FUNCTION ProcessingThread(BYVAL TokenPointer AS LONG) AS LONG
                  LOCAL InputData AS ThreadToken  PTR
                  LOCAL r,t AS LONG
                  
                  InputData=TokenPointer
                  
                  FOR t = 1 TO %LoopLimit
                      FOR r = @InputData.StartIndex TO @InputData.EndIndex
                          a(r)=a(r)+1
                      NEXT
                  NEXT
                  
                  END FUNCTION
                  Last edited by Paul Dixon; 13 Aug 2010, 08:09 AM.

                  Comment


                  • #11
                    >Here's an example. The speech interface blocks ...

                    ... and an excellent example it is!

                    MCM
                    Michael Mattias
                    Tal Systems Inc. (retired)
                    Racine WI USA
                    [email protected]
                    http://www.talsystems.com

                    Comment


                    • #12
                      I recently wrote a simple program that uses threading in very simple ways just to see how easy PB made it in case I wanted to use it at some point. Here's the code:

                      http://www.powerbasic.com/support/pb...806#post349806

                      Barry

                      Comment

                      Working...
                      X