Announcement

Collapse
No announcement yet.

Create thread within a thread

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

  • Create thread within a thread

    I'am working on an NT service. According to some guidelines i've read, one should create a thread when the SCM starts the service. But with one single thread i can't do all the work, so i need more threads.
    Is it possible to use my first thread as an administrative thread and create new threads that should do the work (read/write files, named pipes, etc...)?

    Thanks.
    I'am still confused...but on a higher level.

  • #2
    Yes.

    but be careful exchanging data/variables.
    Using a global variable and share it among threads you will get trouble at some point.
    You'll need critical sections to obtain a variables data (if possibly shared)

    When the app starts you may assume the winmain being executed in the main thread.
    (So it is a thread by itself)
    hellobasic

    Comment


    • #3
      You seemed to have solved your immediate problem, but just to avoid any possible confusion by multi-threaded programs newbies:

      Multiple Threads of Execution within a process have no parent/child relationship; all are equal - siblings if you will. Additional threads of execution may be lauched at any point within a process with exactly zero change in behavior.

      THREAD CREATE executes the function named in the statement in a new thread of execution; any functions called from that function also execute in that new thread of execution. When the thread function completes, the thread object continues to exist only as long as any process - including the current process - maintains an open handle to it.

      Using a global variable and shar[ing] it among thread [functions] you will get [into] trouble at some point
      Amen, my brother!

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

      Comment


      • #4
        :laugh:
        hellobasic

        Comment


        • #5
          This is why threaded variables were added.
          Forum: http://www.jose.it-berater.org/smfforum/index.php

          Comment


          • #6
            I don't know if tls is equal to using a global var with critical section.
            The pb help speaks about maintaining copies of the variable for each thread which is imo not the same as using a global with cs.
            hellobasic

            Comment


            • #7
              Thanks for your qualified input.

              I've done some programs with multithreading. Best practice was using a global array of long integers to hold the thread handles, sharing data with CS, using copies of 'globals' only as 'threaded' variables.
              As long as my
              GLOBAL ghThread() as long
              array works i can write my own routine to suspend or close active threads when commanded by the SCM.
              I'am still confused...but on a higher level.

              Comment


              • #8
                I am really talking about having a global variable like for example a global hInstance as dword situation.
                When two different threads want access to it's contents it might crash the app.
                (Just by reading the value is enough to crash)

                afaik, this depends on the cpu and if the var is dword aligned in memory etc. etc.
                hellobasic

                Comment


                • #9
                  Any variable can ALWAYS be read without protection.

                  If it's a DWORD (32 bit integer) you can write it totally thread-safely using the InterlockedIncrement and/or InterlockedExchange functions.

                  Note that the Interlocked* functions do what they do, which may not be what you want.

                  Also, the SDK-style counterpart to THREADed variables is Thread Local Storage.. and it being your lucky day, here's a demo of same:Terminate Worker Threads Using Windows Events (and Using Thread Local Storage) Demo Dec 23 2005
                  Michael Mattias
                  Tal Systems Inc. (retired)
                  Racine WI USA
                  [email protected]
                  http://www.talsystems.com

                  Comment


                  • #10
                    Can't find the topic and usage of simultaneous reading a variable.
                    I ever had to solve an issue and afaik i had this issue.. maybe not, long time ago.

                    Though for the readers you may consider reading this topic anyway.
                    While it says reading or writing i asume they actually meant read and writting at the same time.

                    http://www.powerbasic.com/support/fo...ML/002294.html
                    hellobasic

                    Comment


                    • #11
                      I just drew up this simple demonstration of using globals with more than one thread:

                      http://www.powerbasic.com/support/pb...356#post270356
                      kgpsoftware.com | Slam DBMS | PrpT Control | Other Downloads | Contact Me

                      Comment


                      • #12
                        While it says reading or writing i asume they actually meant read and writting at the same time.
                        You can't. The computer can only do one thing at a time... unless you get into multiple CPUs, which distribute the load by thread of execution.

                        Using a GLOBAL variable without protection in this case will definitely get you into deep doo-doo.
                        Michael Mattias
                        Tal Systems Inc. (retired)
                        Racine WI USA
                        [email protected]
                        http://www.talsystems.com

                        Comment


                        • #13
                          Sample program thread in thread

                          I see opionions are not equal, so i made a little test with PBCC 4.0.3. Tested with XP/Vista on 3.4 GHZ HT with 900 threads in total (above 920 it becomes slow), change the mx-value in PBMAIN.
                          Also, it seems to make no difference if you INCR/DECR or use InterLockedIncement/InterlockedDecrement.
                          Creating threads from within a thread seems to be working.


                          Code:
                          #COMPILE EXE
                          #DIM ALL
                          #INCLUDE "WIN32API.INC"
                          
                          GLOBAL gTerminate   AS DWORD
                          GLOBAL gTermSubTh   AS DWORD
                          GLOBAL ghThreadW()  AS DWORD
                          GLOBAL ghThreadR()  AS DWORD
                          GLOBAL gTest        AS DWORD
                          
                          FUNCTION thWorkerUp( BYVAL number AS LONG ) AS LONG
                          
                              LOCAL erg   AS DWORD
                              LOCAL i     AS LONG
                              LOCAL r     AS LONG
                          
                              THREAD CREATE thWorkerDown(number) TO ghThreadR(number)
                          
                              RANDOMIZE
                              FOR i = 1 TO 10000
                                  IF gTerminate = %True THEN
                                      gTermSubTh = %True
                                      DO
                                          THREAD STATUS ghThreadR(number) TO erg
                                          SLEEP 5
                                      LOOP UNTIL erg <> &H103
                                      FUNCTION = -1
                                      EXIT FUNCTION
                                  END IF
                                  'erg = InterlockedIncrement( gTest )
                                  INCR gTest
                                  r = RND(1, 10)
                                  SLEEP r
                              NEXT i
                              FUNCTION = gTest
                          
                          END FUNCTION
                          
                          
                          FUNCTION thWorkerDown( BYVAL number AS LONG ) AS LONG
                          
                              LOCAL erg   AS DWORD
                              LOCAL i     AS LONG
                              LOCAL r     AS LONG
                          
                              RANDOMIZE
                              FOR i = 1 TO 10000
                                  IF gTermSubTh = %True THEN
                                      FUNCTION = -1
                                      EXIT FUNCTION
                                  END IF
                                  'erg = InterlockedDecrement( gTest )
                                  DECR gTest
                                  r = RND(1, 10)
                                  SLEEP r
                              NEXT i
                              FUNCTION = gTest
                          
                          END FUNCTION
                          
                          
                          
                          FUNCTION PBMAIN () AS LONG
                          
                              LOCAL i         AS LONG
                              LOCAL mx        AS LONG
                              LOCAL lState    AS LONG
                          
                              mx      = 499
                              gTest   = 100
                              DIM ghThreadW( 1 TO mx )
                              DIM ghThreadR( 1 TO mx )
                          
                              FOR i = 1 TO mx
                                  THREAD CREATE thWorkerUp(i) TO ghThreadW(i)
                                  STDOUT "thread"+STR$(i)+" up and running"
                                  SLEEP 1
                              NEXT i
                              SLEEP 5
                          
                              COLOR 4
                              STDOUT "press any key to terminate threads..."
                              COLOR 7
                              DO WHILE INKEY$=""
                                  STDOUT STR$(gTest);
                                  SLEEP 5
                              LOOP
                          
                              gTerminate = %True
                              COLOR 15
                              STDOUT
                              STDOUT "terminating threads, this may take a while..."
                              FOR i = 1 TO mx
                                  DO
                                      SLEEP 10
                                      THREAD STATUS ghThreadW(i) TO lState
                                  LOOP UNTIL lState <> &H103
                                  STDOUT "thread"+STR$(i)+" up/down terminated"
                              NEXT i
                          
                              COLOR 4
                              STDOUT "press any key to exit program..."
                              COLOR 7
                              DO WHILE INKEY$=""
                                  SLEEP 5
                              LOOP
                          
                          END FUNCTION
                          I'am still confused...but on a higher level.

                          Comment


                          • #14
                            Also, it seems to make no difference if you INCR/DECR [without the use of a synchronization oject] or use InterLockedIncement/InterlockedDecrement.
                            You've been lucky. And when this does come back to bite you in a tender place, it will essentially be impossible to reproduce it so you can fix it and get your customer to call off the large men with no necks wearing dark suits.

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

                            Comment


                            • #15
                              Increment and decrement are atomic events. They don't explode, but they can't be split into smaller parts.
                              The CPU sees them as a single, indivisible, non-interruptable action so I'm not sure what the supposed problem is.

                              It'd be different if you used X=X+1 which could, potentially, be iterrupted after the X was read and X modifed in another thread before the result was written in the current thread.

                              I suppose it could be argued that the way the compiler implements INCR X might not be with the CPU opcode !INC X but that would be silly.

                              Paul.

                              Comment


                              • #16
                                >INCR X might not be with the CPU opcode !INC X but that would be silly.

                                I'm no assembly language guy but wouldn't the compiler need to PUSH something into a register before doing INC? i.e, 'INCR' = 'push' PLUS 'inc' , conceivably interrupted between same?

                                ????

                                Inquiring Minds ... really don't give a rat's butt in this case, because it is sloppy, careless and lazy programming technique to try to do multi-threaded programs 'on the cheap' by relying on the way the compiler translates source code instead of doing it the Right Way using synchronization objects.

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

                                Comment

                                Working...
                                X