Announcement

Collapse
No announcement yet.

Processing Array Elements in Threads?

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

  • Processing Array Elements in Threads?

    I need to create an array of strings, then have background threads process the individual elements (one thread for each string element). I wrote this sample program which seems to work, but when I try the same technique in my main program it crashes. So I don't know if I have a different error in my main program, or if I'm passing the array element to the threads incorrectly. I'm new to thread processing so any tips would be appreciated.

    Code:
    #COMPILE EXE
    DEFLNG a-z
    
    FUNCTION PBMAIN () AS LONG
      DIM hnd(10) AS LONG
      DIM stuff(10) AS STRING
    
      FOR a=1 TO 10
        stuff$(a)="This "+FORMAT$(a)
      NEXT a
    
    
      FOR a=1 TO 10
        THREAD CREATE test(VARPTR(stuff$(a))) TO hnd(a)
      NEXT a
    
    
      DO
        SLEEP 10
      LOOP UNTIL THREADCOUNT =1
    
      FOR a=1 TO 10
        THREAD CLOSE hnd(a) TO hnd(a)
      NEXT a
    
      r$=""
      FOR a=1 TO 10
        r$=r$+stuff$(a)+$CRLF
      NEXT a
      MSGBOX r$
    
    
    END FUNCTION
    
    
    THREAD FUNCTION test(BYVAL x AS STRING PTR)
      @x=@x+" and That"
    END FUNCTION
    Anthony Watson, Mountain Software
    www.mountainsoftware.com

  • #2
    1. What error code does main program report?

    2. The THREAD FUNCTION in main progam - does it also concatinate strings? Or does it accidentally add a numeric to pointer x? ((doing @ at an invalid address?)) (((strings need to change location (often) when they get larger. A bigger change in main program (than in demo) may make @x=@x + (longer string) violate another string's space))) [[WAG cuz failing code not shown!]]

    Cheers,
    Dale

    Comment


    • #3
      Dale,

      1. No error codes. The program just crashes and closes. I assume the way I am referencing the array element is changing the address of the string in the array. I'm not sure how to reference a single element in the array from a background thread.

      2. The array in my main program is a holding spot for strings to process. It scans the array looking for an empty element, and saves the new string there. The background threads watch for text in the associated element. When something appears it processes the string, then clears the element so the main program can save a new string in that spot.

      Basically, I just need a way to distribute strings to the background threads as they become available. For example, to process 100 strings with 10 background threads. I don't know how many strings I have in advance, so I can't divide them among the threads from the start.

      Anthony Watson, Mountain Software
      www.mountainsoftware.com

      Comment


      • #4
        Anthony, your program crashes out abruptly is probably due to out of dimension error -- as Powerbasic does that without giving error
        it actually GPF.

        What you need to do is to use GLOBAL to globalize your array as in :

        Code:
        #COMPILE EXE
        #DIM ALL
        
        GLOBAL hnd() AS LONG
        GLOBAL stuff() AS STRING
        
        FUNCTION PBMAIN () AS LONG
          REDIM hnd(1 TO 10)
          REDIM stuff(1 TO 10)
        
          LOCAL a AS LONG
          LOCAL r$
        
          FOR a=1 TO 10
            stuff$(a)="This "+FORMAT$(a)
          NEXT a
        
        
          FOR a=1 TO 10
            THREAD CREATE test(VARPTR(stuff$(a))) TO hnd(a)
          NEXT a
        
        
          DO
            SLEEP 10
          LOOP UNTIL THREADCOUNT =1
        
          FOR a=1 TO 10
            THREAD CLOSE hnd(a) TO hnd(a)
          NEXT a
        
          r$=""
          FOR a=1 TO 10
            r$=r$+stuff$(a)+$CRLF
          NEXT a
          MSGBOX r$
        
        
        END FUNCTION
        
        
        THREAD FUNCTION test(BYVAL x AS STRING PTR)
          @x=@x+" and That"
        END FUNCTION

        Comment


        • #5
          This code works now !

          Comment


          • #6
            Sorry, the below composed two posts ago, but kept getting sever error when pressing "Post Reply"

            An array of type STRING does not contain strings, it contains string headers (length and pointer to first character). When STRINGs change length it is safest to assume they also change location. With headers, or at least pointers, in two (or more) variables. the older one will be invalid when program flow gets back to it.

            Don't need your whole program (I hope), but demo code closer to what you're doing help me (or someone) help you.

            Cheers,
            Dale

            Comment


            • #7
              This code works now !
              ?????

              Post 1 code worked as is (for me).

              What's GLOBAL got to with it? (unless PBMAIN is ending before a (/last) thread finishes (on your PC).
              Dale

              Comment


              • #8
                DIMing arrays as 1 to 10 also does not matter. Anthony had DIM as (10). which made arrays with 0 thru 10 elements. The 11th element is "0". In his FOR/NEXT loops he ref'ed 1 thru 10. Nobody said you must use element 0, and Help says code is more efficient without a lower bound specified. So where did "out of bound error" occur?

                Cheers,
                Dale

                Comment


                • #9
                  I, because there is no code showing the issue, am of the opinion that the problem is in the code of the main program and it only appears that it is related to the use of THREADs. #DEBUG DISPLAY ON in the main program may show where the issue really is.
                  Rod
                  "To every unsung hero in the universe
                  To those who roam the skies and those who roam the earth
                  To all good men of reason may they never thirst " - from "Heaven Help the Devil" by G. Lightfoot

                  Comment


                  • #10
                    Anthony

                    I do not understand all this thread stuff

                    But I have had the same issue with arrays when I have tried to update an array beyond its limits. The program just bombs out with no message.

                    The way I got around it was to define the size of an array not by using numbers but saying
                    array_max as long = 10

                    Then DIM using array_max

                    Incidentally I always DIM as '1 to array_max' and this seems to be a better standard.

                    And then I had a macro which checked that the qualifier that I was using was not too big compared to array_max. I used this macro to check all instructions which addressed the array and the macro displays all useful debug information. Once everything was debugged, you just comment out the macro and carry on. Although while the macro was complicated, the first instruction exited if everything was ok. It was' If qualifier > array_max then do something else carry on' so it is not a big overhead

                    This might be overkill if you only have one array. In my case I had many arrays and I needed to know which one was bombing out. The discipline of using a preset array size worked for me. it also allowed me to change array sizes easily and in a controlled fashion.

                    In your case, I suspect without knowing that you think you have a thread issue when you only have an array issue.
                    [I]I made a coding error once - but fortunately I fixed it before anyone noticed[/I]
                    Kerry Farmer

                    Comment


                    • #11
                      Anthony,

                      The string pointers that you are passing may be going out of scope in your main program.

                      You are passing pointers to local strings in your test program but they are dimmed in PBMain so are valid(in scope) for the life of the program.

                      Probably you need to pass Static or Global pointers in your other program?
                      Last edited by Dave Biggs; 11 Jul 2018, 11:37 PM. Reason: Grammar
                      Rgds, Dave

                      Comment


                      • #12
                        If its a Byte Array it may not be of interest, but to Access Members of a String-Array, especially if you plan to change them - you should use a common shared procedure that is declared as "THREADSAFE" and therefore has a Semaphore builtin. Otherwise there is a small risk that one Thread makes changes in the memory-management of the Array (for example inserts characters) at the same time the other thread treis to read the Array and this may lead to problems. Because in such case pointers to Array-Elements may move.
                        --Theo Gottwald
                        ------------------------------------------------
                        76706 Dettenheim * Germany * info@it-berater.org
                        ------------------------------------------------
                        Joses Forum * Theo's Link Site * IT-Berater.org

                        Comment


                        • #13
                          Theo,

                          I do think part of the issue was string pointers were changing from the time the main program assigned the string till the thread accessed it, or vice versa. I also discovered there were serious timing issues the way I was trying to do it. I would save a string in the array, and five or more threads would access it immediately, some finishing and clearing the string while the next thread was grabbing it. Obviously not what I had in mind.

                          After fighting with the string array idea for days I decided that approach was more trouble than it was worth. I switched to a new system where threads are created as needed, passing one string to each thread as it's created. It accomplishes what I was wanting to do, seems to be faster, and uses less memory since I don't have to store the strings in an array. I have a couple minor issues I still need to take care of, such as waiting for the threads to finish and whatnot, but those should be easy to fix when I get the time to work on it.

                          Thanks for the feedback everyone!
                          Anthony Watson, Mountain Software
                          www.mountainsoftware.com

                          Comment

                          Working...
                          X