Fork ()

Da Gambas-it.org - Wikipedia.

La fuzione fork()

__pid_t fork (void)

crea una copia del processo. Il processo originario è chiamato "Padre", il processo clone è chiamato "Figlio".

Se la funzione fork() ha successo, essa ritorna il valore 0 (zero) al processo Figlio, e ritorna al processo Padre il valore del pid del processo Figlio (che sarà esclusivo e diverso dal pid del processo Padre). In caso di errore la funzione ritorna -1.

L'esecuzione del processo Padre è svincolata da quella del processo 'Figlio; e pertanto procedono indipendentemente l'una dall'altra.


Volendola utilizzare direttamente in Gambas, bisognerà dichiararla con Extern, nonché dichiarare la libreria di C: libc.so.6, nella quale la funzione è contenuta:

Private Extern fork() As Integer In "libc:6"

Mostriamo di seguito alcuni esempio di uso in Gambas.

1° esempio

Library "libc:6"

' __pid_t fork (void)
' Clone the calling process, creating an exact copy.
Private Extern fork() As Integer


Public Sub Main()
 
 Dim pid, i, n As Integer
 
   pid = fork()
   
   If pid = 0 Then   ' "fork()" ritorna 0 al processo "Figlio".
' Dunque qui siamo nel processo "Figlio":
     For i = 0 To 9
       Print "Figlio: "; i
       Wait 0.3
     Next
     Quit
   Else If pid > 0   ' "fork()" ritorna al processo "Padre" il pid del processo "Figlio".
' Dunque qui siamo nel processo "Padre":
     For n = 0 To 9
       Print "Padre: "; n
       Wait 0.6
     Next
   Else
     Error.Raise("Errore nel fork !")
   Endif
  
End


2° esempio

In questo esempio vengono creati 4 Figli di un medesimo processo Padre:

Library "libc:6"
 
' __pid_t fork (void)
' Clone the calling process, creating an exact copy.
Private Extern fork() As Integer

' __pid_t getpid (void)
' Get the process ID of the calling process.
Private Extern getpid() As Integer

' __pid_t getppid (void)
' Get the process ID of the calling process's parent.
Private Extern getppid() As Integer

' void exit(int status)
' Terminates the calling process immediately. Any open file descriptors belonging to the process are closed.
Private Extern exit_C(status As Integer) Exec "exit"

' __pid_t wait (__WAIT_STATUS __stat_loc)
' Wait for a child to die.
Private Extern wait_C(__stat_loc As Pointer) As Integer Exec "wait"


Public Sub Main()
 
 Dim b As Byte
 Dim i As Integer
 Dim pid As New Integer[4]
 
 
  For b = 0 To pid.Max
    
    pid[b] = fork()
    
    If pid[b] = 0 Then
      Print "Figlio con PID: "; getpid(); "  -  Il PID del Padre è "; getppid()
      exit_C(0)
    Else
      i = pid[b]
      wait_C(VarPtr(i))      ' Aspetta che il figlio sia creato
    Endif
  
  Next
  
End


3° esempio

In quest'altro esempio, facendo anche uso delle funzioni esterne "mmap( )" e "wait( )", si provvederà a passare dei dati per mezzo di una variabile di tipo Puntatore dal processo Figlio al processo Padre.

Tale variabile di tipo Puntatore rappresenterà la memoria condivisa (shared memory) tra il processo Padre e quello Figlio.

Library "libc:6"

Private Const PROT_READ As Integer = 1
Private Const PROT_WRITE As Integer = 2
Private Const MAP_SHARED As Integer = 1
Private Const MAP_ANONYMOUS As Integer = 32

' void *mmap (void *__addr, size_t __len, int __prot, int __flags, int __fd, __off_t __offset)
' Map addresses starting near ADDR and extending for LEN bytes.
Private Extern mmap(__addr As Pointer, __len As Long, __prot As Integer, __flags As Integer, __fd As Integer, __offset As Long) As Pointer

' __pid_t fork(void)
' Clone the calling process, creating an exact copy.
Private Extern fork() As Integer

' __pid_t wait (__WAIT_STATUS __stat_loc)
' Wait for a child to die.
Private Extern wait_C(__stat_loc As Pointer) As Integer Exec "wait"


Public Sub Main()
 
 Dim p As Pointer
 Dim x, pid As Integer
 Dim st As Stream
 
' Crea la memoria condivisa:
   p = mmap(0, SizeOf(gb.Pointer), PROT_READ Or PROT_WRITE, MAP_SHARED Or MAP_ANONYMOUS, -1, 0)
   
   pid = fork()
   Select Case pid
     Case -1
     Case 0      ' Processo Figlio
' Il processo figlio gli dà un valore all'area di memoria condivisa:
       st = Memory p For Write
       Write #st, "Gambas"
       st.Close
     Case Else   ' Processo Padre
       wait_C(VarPtr(x))    ' Si potrebbe utilizzare anche un semplice " Sleep 0.1 "
' Il padre stampa il valore scritto dal processo figlio:
       Print "Il valore della shared memory è: "; String@(p)
   End Select
  
End



Riferimenti