Menu

SPAWN command?

Programs
2021-04-21
2024-01-07
  • Yet Another Troll

    This is my first attempt to use the SPAWN command. Can it be used on Android? Is busy waiting like this my only option? Is it best reserved for compute-bound things like long calculations, so calls to I/O or graphics don't clobber each other? Am I more or less on the right track?

    Thanks!

    Program OnMyLastThread
    
     Dim ThreadResults(10), ThreadFlags%(10)
     Clr t_i%, t_x, t_y, t_z, t_launch%
     Clr Done%, i%
    
     For i% = 0 To UBound(ThreadResults()) - 1
    
      Print "Thread "; i%;
      Flush
    
      ! Set parameters in global variables that the spawned
      ! thread can access and copy into local variables
      t_i% = i%
      t_x = i% Mod 3
      t_y = 10
      t_z = 10
      t_launch% = 0
    
      ! T minus zero!
      Spawn CalcWorker
    
      ! Twiddle our thumbs until the thread says it's
      ! done making local copies of its parameters
      While t_launch% = 0
       Pause 0.01
      Wend
    
      Print " launched"
     Next i%
    
     ! Chase our tail until all the threads have reported in
     Repeat
      Done% = 1
      For i% = 0 To UBound(ThreadResults()) - 1
       If ThreadFlags%(i%) = 0 Then
        Done% = 0
       Else If ThreadFlags%(i%) = 1 Then
        Print "Result "; i%, ThreadResults(i%)
        ThreadFlags%(i%) = 2
       EndIf
      Next i%
      Pause 0.01
     Until Done%
    
     Print "OK"
    End
    
    Procedure CalcWorker
     Local i%, x, y, z
     i% = t_i%
     x = t_x
     y = t_y
     z = t_z
     t_launch% = 1
     Pause x
     ThreadResults(i%) = x
     ThreadFlags%(i%) = 1
    Return
    
     
  • Markus Hoffmann

    Markus Hoffmann - 2021-04-21

    Well, as said in the manual:

    This command is not fully implemented and at the moment messes up the
    program execution stack of the interpreter since all internal control
    structures are accessed by two threads. Anyway, in a natively compiled
    program this can work as expected.

    It definitively does not work on WINDOWS and ATARI/TOS.

    On Android maybe. It is realized with the fork() command internally (and this does not behave like threads, which you probably have in mind.) and I am not sure if an app is allowed to fork. I see some comments about this, it works, but the recommendation is: Don't do this. Just don't.

    Also maybe if it is working, it might not do what you expect it to do: Each of the spawned procedures has their own variables, so they cannot share them while they are running.

    Sorry.

     
    • Yet Another Troll

      No problem! So don't use SPAWN in anything other than gcc/tcc compiled programs for Unix/Linux? At least in the interpreter under Android and Windows, SPAWN appears to behave just like GOSUB instead of making the interpreter go haywire. But all the idle cores on my Android and Windows devices! :'-(

       
    • Yet Another Troll

      Maybe FORK will be good enough, if it and the SHM commands work reasonably on every platform of interest, hopefully also on Android.

      Umm, wut

      ...
       Print "SHM_MALLOC("; 4 * Cores% * (NItems% + 2); ", 4711)"
       ! sdid% = MALLOC(4 * Cores% * (NItems% + 2))
       sdid% = SHM_MALLOC(4 * Cores% * (NItems% + 2), 4711)
       Print "Shared memory ID = "; sdid%
      
       ! sd% = sdid%
       sd% = SHM_ATTACH(sdid%)
       If True ! c0% = 0
        Print "Shared memory attached at "; Hex$(sd%)
       EndIf
      ...
      

      results in, at least in Windows 10 64-bit Version 10.0.19045.3803,

      > run
      Trials? 1000
      64 items, 64 slots, 1000 trials
      SHM_MALLOC(8448, 4711)
      ERROR at line 41: Unknown Error SHM_MALLOC
      >
      

      Where is MAP documented? Can mapped files be (ab)used to implement shared memory?

       
  • Markus Hoffmann

    Markus Hoffmann - 2021-04-22

    Well, to make use of more Processor-cores, I had the idea to use OpenMP wherever it makes sense, but, in the end, I thought: who needs that? It is a big effort for little gain. The FORK kommand works at least. And one can split the most critical tasks in several sub-programs which can be excecuted (with SYSTEM) in parallel, if needed. Interprocess communications via files (/run/shm/) or so. To keep it easy. But If you really want, and can provide help, one could improve X11-basic step by step also in that direction.

     
    • Yet Another Troll

      Oh no, this is starting to look too much like MapReduce

       
    • Yet Another Troll

      I had a few more bad ideas regarding SPAWN and maybe extending AFTER and EVERY to work with threads. Maybe it should be possible to pass additional parameters to SPAWN that would then be passed to the spawned proc, and then when threads exit, a proc in the main program could be triggered, if only to set a flag or interrupt a PAUSE. So, something like this,

      For i% = 0 To n%
      Spawn Worker, i%, j%, k%, ...
      Next i%

      oops% = True
      After Threads AllWorkersDone
      Pause 60
      If oops%
      Print "Timeout, threads are still running"
      Else
      Print "All threads completed"
      EndIf

      ...or maybe something like,

      oops% = True
      i% = n%
      Every Thread OneWorkerDone
      Do
      Print i%; " threads remaining"
      Exit If 0 = %i
      oops% = True
      Pause 60
      Exit if oops%
      Loop
      If 0 = i%
      Print "All threads completed"
      Else If oops%
      Print "Timeout, "; i%; " threads are still running"
      Else
      Print "Threads are hard, let's go shopping!"
      EndIf

      Procedure Worker(i%, j%, k%, ...)
      ! do stuff
      Return

      Procedure AllWorkersDone
      oops% = False
      Return

      Procedure OneWorkerDone
      Dec i%
      oops% = False
      Return

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.