Sharing common data betwen different threads

in the example, both threads share the same group declared globally.
Of course, this example lacks synchronization.
I would like to have the group declared inside one of the threads,
but I can’t find the way to pass the reference to the other thread.

 PROGRAM
  MAP
T1  PROCEDURE()
T2  PROCEDURE()
  END

grp       GROUP,TYPE
f1          LONG
f2          LONG
          END

Window       WINDOW('CAPTION'),AT(,,260,100),SYSTEM,GRAY,MAX
    BUTTON('Button1'),AT(18,22),USE(?BUTTON1)
             END

g1        GROUP(grp).

!-------------------------------------
  CODE
  OPEN(Window)
  ACCEPT
    IF Event() = EVENT:Accepted THEN
      CASE Field()
      OF ?Button1
        Start(T1)
        Start(T2)
      END !case
    END !if 
  END !accept
  CLOSE(Window)
!=====================================        
T1  PROCEDURE()
G   &GRP
  CODE
  G &= G1
  Message(g.f1)
  
!=====================================        
T2  PROCEDURE()
G   &GRP
  CODE
  G &= G1
  g.f1 = 2
!=====================================

Ways to share data between threads:

  1. Place the data at a shared scope
    this could be global, or modular data
    modular data could the same module that both threads code lives in
    or the modular data could be where accessor functions (methods) live.

    it’s worth mentioning that in the case of data with the ,THREAD attribute
    that you can use INSTANCE to get a reference to the threaded data of another thread

  2. Pass the data as you START the thread
    note the prototype for procedures you START only allow parameters of type STRING
    and must take 0,1,2 or 3 string arguments.

    since you’re wanting to pass by address you would write something like:

  PROGRAM
  MAP 
      T1 PROCEDURE(STRING xAddressOfGroup)
  END

GRP GROUP,TYPE
F1     LONG
F2     LONG
    END 
G1  LIKE(GRP)

  CODE
   !....
   TheNewThread = START(T1, , ADDRESS(G1) )

T1 PROCEDURE(STRING xAddressOfGroup)  
PassedGrp &GRP
   CODE
   PassedGrp &= 0 + xAddressOfGroup  
   PassedGrp &= ( xAddressOfGroup )  
   ! the right hand side needs to be an expression which is then interpreted as an address
  1. Pass the data later on,
    this is often accomplished via a NOTIFY
    or for other types of data you might use a POST
    where the post informs the thread to go check some global data

Synchronization objects are appropriate - no matter how you shared the data.
When you have multiple threads working with shared data AND that data can be altered by any of the threads while other threads are potentially working with the data (reading or writing)

Another option is something like this class. You could have a global instance of the class, and just use SetValue(‘UniqueName’,YourValue), GetValue(‘UniqueName’). The .inc is in the same folder on the site. https://github.com/clarionmag/ClarionMagLibrary/blob/master/libsrc/CML_Data_Datafier.clw.
I might design it differently, if I were to write it today, but it works.

mark, thanks for your answer.
g &= 0 + p0
g &= (p0)
did the trick.
I will check the dissasembly to try to understand what is the difference.
Jeff, thanks. There is a lot in this class.
regards
Marcelo Sanseau