Differenze tra le versioni di "Fork ()"

Da Gambas-it.org - Wikipedia.
 
Riga 1: Riga 1:
 
La fuzione '''fork()'''
 
La fuzione '''fork()'''
 
  __pid_t fork (void)
 
  __pid_t fork (void)
crea una copia del processo. Il processo originario è chiamato "''Padre''", il processo clone è chiamato "''Figlio''".
+
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.
+
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.
 
L'esecuzione del processo ''Padre'' è svincolata da quella del processo 'Figlio''; e pertanto procedono indipendentemente l'una dall'altra.
Riga 10: Riga 10:
 
Volendola utilizzare direttamente in Gambas, bisognerà dichiararla con Extern, nonché dichiarare la libreria di C: libc.so.6, nella quale la funzione è contenuta:
 
Volendola utilizzare direttamente in Gambas, bisognerà dichiararla con Extern, nonché dichiarare la libreria di C: libc.so.6, nella quale la funzione è contenuta:
 
  Private <FONT Color=#B22222>Extern fork()</font> As Integer In "libc:6"
 
  Private <FONT Color=#B22222>Extern fork()</font> As Integer In "libc:6"
 
+
Mostriamo di seguito alcuni esempi di uso in Gambas.
Mostriamo di seguito alcuni esempio di uso in Gambas.
 
  
 
===1° esempio===
 
===1° esempio===
Riga 21: Riga 20:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
    
 
    
 
   Dim pid, i, n As Integer
 
   Dim pid, i, n As Integer
 
    
 
    
    pid = <FONT Color=#B22222>fork()</font>
+
  pid = <FONT Color=#B22222>fork()</font>
 
      
 
      
    If pid = 0 Then  <FONT Color=gray>' ''"fork()" ritorna 0 al processo "Figlio".''
+
  If pid = 0 Then  <FONT Color=gray>' ''"fork()" ritorna 0 al processo "Figlio".''
 
  ' ''Dunque qui siamo nel processo "'''Figlio'''":''</font>
 
  ' ''Dunque qui siamo nel processo "'''Figlio'''":''</font>
      For i = 0 To 9
+
    For i = 0 To 9
        Print "Figlio: "; i
+
      Print "Figlio: "; i
        Wait 0.3
+
      Wait 0.3
      Next
+
    Next
      Quit
+
    Quit
    Else If pid > 0  <FONT Color=gray>' ''"fork()" ritorna al processo "Padre" il pid del processo "Figlio".''
+
  Else If pid > 0  <FONT Color=gray>' ''"fork()" ritorna al processo "Padre" il pid del processo "Figlio".''
 
  ' ''Dunque qui siamo nel processo "'''Padre'''":''</font>
 
  ' ''Dunque qui siamo nel processo "'''Padre'''":''</font>
      For n = 0 To 9
+
    For n = 0 To 9
        Print "Padre: "; n
+
      Print "Padre: "; n
        Wait 0.6
+
      Wait 0.6
      Next
+
    Next
    Else
+
  Else
      Error.Raise("Errore nel fork !")
+
    Error.Raise("Errore nel fork !")
    Endif
+
  Endif
 
    
 
    
  '''End'''
+
  End
  
  
Riga 72: Riga 71:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
    
 
    
 
   Dim b As Byte
 
   Dim b As Byte
 
   Dim i As Integer
 
   Dim i As Integer
 
   Dim pid As New Integer[4]
 
   Dim pid As New Integer[4]
 
+
    
+
   For b = 0 To pid.Max
  For b = 0 To pid.Max
+
    pid[b] = fork()
   
+
    If pid[b] = 0 Then
    pid[b] = fork()
+
      Print "Figlio con PID: "; getpid(); "  -  Il PID del Padre è "; getppid()
   
+
      exit_C(0)
    If pid[b] = 0 Then
+
    Else
      Print "Figlio con PID: "; getpid(); "  -  Il PID del Padre è "; getppid()
+
      i = pid[b]
      exit_C(0)
+
      wait_C(VarPtr(i))      <FONT Color=gray>' ''Aspetta che il figlio sia creato''</font>
    Else
+
    Endif
      i = pid[b]
+
  Next
      wait_C(VarPtr(i))      <FONT Color=gray>' ''Aspetta che il figlio sia creato''</font>
+
    Endif
+
  End
 
 
  Next
 
 
 
  '''End'''
 
  
  
 
===3° esempio===
 
===3° esempio===
In quest'altro esempio, facendo anche uso delle funzioni esterne "''[[Creare_una_mappatura_della_memoria_mediante_mmap()|mmap( )]]''" e "''wait( )''", si provvederà a passare dei dati per mezzo di una variabile di tipo ''Puntatore'' dal processo ''Figlio'' al processo ''Padre''.
+
In quest'altro esempio, facendo anche uso delle funzioni esterne "[[Creare_una_mappatura_della_memoria_mediante_mmap()|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''.
+
Tale variabile di tipo ''Puntatore'' rappresenterà la memoria condivisa (''shared memory'' ) tra il processo ''Padre'' e quello ''Figlio''.
 
  Library "libc:6"
 
  Library "libc:6"
 
   
 
   
Riga 120: Riga 115:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
    
 
    
 
   Dim p As Pointer
 
   Dim p As Pointer
Riga 127: Riga 122:
 
    
 
    
 
  <FONT Color=gray>' ''Crea la memoria condivisa:''</font>
 
  <FONT Color=gray>' ''Crea la memoria condivisa:''</font>
    p = mmap(0, SizeOf(gb.Pointer), PROT_READ Or PROT_WRITE, MAP_SHARED Or MAP_ANONYMOUS, -1, 0)
+
  p = mmap(0, SizeOf(gb.Pointer), PROT_READ Or PROT_WRITE, MAP_SHARED Or MAP_ANONYMOUS, -1, 0)
 
      
 
      
    pid = fork()
+
  pid = fork()
    Select Case pid
+
  Select Case pid
      Case -1
+
    Case -1
      Case 0      <FONT Color=gray>' '''''Processo Figlio'''''</font>
+
    Case 0      <FONT Color=gray>' '''''Processo Figlio'''''</font>
 
  <FONT Color=gray>' ''Il processo figlio gli dà un valore all'area di memoria condivisa:''</font>
 
  <FONT Color=gray>' ''Il processo figlio gli dà un valore all'area di memoria condivisa:''</font>
        st = Memory p For Write
+
      st = Memory p For Write
        Write #st, "Gambas"
+
      Write #st, "Gambas"
        st.Close
+
      st.Close
      Case Else  <FONT Color=gray>' '''''Processo Padre'''''</font>
+
    Case Else  <FONT Color=gray>' '''''Processo Padre'''''</font>
        wait_C(VarPtr(x))    <FONT Color=gray>' ''Si potrebbe utilizzare anche un semplice " Sleep 0.1 "''</font>
+
      wait_C(VarPtr(x))    <FONT Color=gray>' ''Si potrebbe utilizzare anche un semplice " Sleep 0.1 "''</font>
 
  <FONT Color=gray>' ''Il padre stampa il valore scritto dal processo figlio:''</font>
 
  <FONT Color=gray>' ''Il padre stampa il valore scritto dal processo figlio:''</font>
        Print "Il valore della shared memory è: "; String@(p)
+
      Print "Il valore della shared memory è: "; String@(p)
    End Select
+
  End Select
 
    
 
    
  '''End'''
+
  End
 
 
  
  

Versione attuale delle 16:17, 14 giu 2024

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 esempi 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