Fork (): differenze tra le versioni
Nessun oggetto della modifica |
Nessun oggetto della modifica |
||
| (Una versione intermedia di uno stesso utente non è mostrata) | |||
| 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 | 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. | |||
===1° esempio=== | |||
Library "libc:6" | Library "libc:6" | ||
| Riga 19: | Riga 20: | ||
Public Sub Main() | |||
Dim pid, i, n As Integer | Dim pid, i, n As Integer | ||
pid = <FONT Color=#B22222>fork()</font> | |||
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 | |||
Print "Figlio: "; i | |||
Wait 0.3 | |||
Next | |||
Quit | |||
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 | |||
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" | |||
<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 | ||
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''. | |||
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 66: | Riga 112: | ||
<FONT Color=gray>' ''__pid_t wait (__WAIT_STATUS __stat_loc)'' | <FONT Color=gray>' ''__pid_t wait (__WAIT_STATUS __stat_loc)'' | ||
' ''Wait for a child to die.''</font> | ' ''Wait for a child to die.''</font> | ||
Private Extern wait_C(__stat_loc As | Private Extern wait_C(__stat_loc As Pointer) As Integer Exec "wait" | ||
Public Sub Main() | |||
Dim p As Pointer | Dim p As Pointer | ||
| Riga 76: | 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) | |||
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> | <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> | <FONT Color=gray>' ''Il padre stampa il valore scritto dal processo figlio:''</font> | ||
Print "Il valore della shared memory è: "; String@(p) | |||
End Select | |||
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