Differenze tra le versioni di "Fork ()"

Da Gambas-it.org - Wikipedia.
 
(2 versioni intermedie di uno stesso utente non sono mostrate)
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.
  
Esempio di uso in Gambas:
+
===1° esempio===
 
  Library "libc:6"
 
  Library "libc:6"
 
   
 
   
Riga 19: 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
 +
    Error.Raise("Errore nel fork !")
 +
  Endif
 +
 
 +
End
 +
 
 +
 
 +
===2° esempio===
 +
In questo esempio vengono creati 4 Figli di un medesimo processo Padre:
 +
Library "libc:6"
 +
 
 +
<FONT Color=gray>' ''__pid_t fork (void)''
 +
' ''Clone the calling process, creating an exact copy.''</font>
 +
Private Extern fork() As Integer
 +
 +
<FONT Color=gray>' ''__pid_t getpid (void)''
 +
' ''Get the process ID of the calling process.''</font>
 +
Private Extern getpid() As Integer
 +
 +
<FONT Color=gray>' ''__pid_t getppid (void)''
 +
' ''Get the process ID of the calling process's parent.''</font>
 +
Private Extern getppid() As Integer
 +
 +
<FONT Color=gray>' ''void exit(int status)''
 +
' ''Terminates the calling process immediately. Any open file descriptors belonging to the process are closed.''</font>
 +
Private Extern exit_C(status As Integer) Exec "exit"
 +
 +
<FONT Color=gray>' ''__pid_t wait (__WAIT_STATUS __stat_loc)''
 +
' ''Wait for a child to die.''</font>
 +
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
 
     Else
       Error.Raise("Errore nel fork !")
+
       i = pid[b]
 +
      wait_C(VarPtr(i))     <FONT Color=gray>' ''Aspetta che il figlio sia creato''</font>
 
     Endif
 
     Endif
 +
  Next
 +
 +
End
 +
 +
 +
===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''.
 +
 +
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
 +
 +
<FONT Color=gray>' ''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.''</font>
 +
Private Extern mmap(__addr As Pointer, __len As Long, __prot As Integer, __flags As Integer, __fd As Integer, __offset As Long) As Pointer
 +
 +
<FONT Color=gray>' ''__pid_t fork(void)''
 +
' ''Clone the calling process, creating an exact copy.''</font>
 +
Private Extern fork() As Integer
 +
 +
<FONT Color=gray>' ''__pid_t wait (__WAIT_STATUS __stat_loc)''
 +
' ''Wait for a child to die.''</font>
 +
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
 +
 
 +
<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)
 +
   
 +
  pid = fork()
 +
  Select Case pid
 +
    Case -1
 +
    Case 0      <FONT Color=gray>' '''''Processo Figlio'''''</font>
 +
<FONT Color=gray>' ''Il processo figlio gli dà un valore all'area di memoria condivisa:''</font>
 +
      st = Memory p For Write
 +
      Write #st, "Gambas"
 +
      st.Close
 +
    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>
 +
<FONT Color=gray>' ''Il padre stampa il valore scritto dal processo figlio:''</font>
 +
      Print "Il valore della shared memory è: "; String@(p)
 +
  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