English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Poiché non è determinato chi esegue per primo tra i processi, dipende dall'algoritmo di pianificazione dei processi del kernel, che è piuttosto complesso. Di conseguenza, è possibile che più processi accedano contemporaneamente alla memoria condivisa, causando errori imprevisti. Il nome 'segnale' sembra misterioso, ma guardando il suo significato inglese, è molto facile capirlo.
semaphore [ˈseməfɔ:(r)] vt. emettere segnale, fare segno;
Simile al ruolo di un comandante.
Ora vediamo l'uso del segnale pseudo-codice.
1、Crea l'identificatore unico del segnale
$ftok = ftok(__FILE__, 'a');
2、Crea l'ID della risorsa di segnale
$sem_resouce_id = sem_get($ftok);
3、Accetta il segnale
sem_acqure($sem_resource_id);
4、Rilascia il segnale
sem_release($sem_resource_id);
5、Distruggi il segnale
sem_remove($sem_resource_id);
Facciamo un esempio non elegante per farci capire l'uso della coda di segnali nella vita quotidiana. Dopo aver capito, possiamo applicarlo al nostro campo di programmazione.
In una compagnia c'è solo un bagno. Quindi quando qualcuno usa il bagno, devono ottenere una chiave di lucchetto (segnalatore) per indicare che il bagno è in uso. Il codice è il seguente:
sem_acqure($sem_resource_id);
Dopo che l'operatore ha finito di usare il bagno, è necessario aprire il lucchetto e rilasciare il lucchetto (segnalatore), indicando che ora è possibile permettere a qualcun altro di usarlo. Il codice è il seguente:
sem_release($sem_resource_id);
Con un semplice lucchetto, possiamo sapere se il bagno (memoria condivisa) è disponibile. Questo esempio non è elegante, ma spiega il problema. Questo blog ha anche un sapore, non è facile......Di seguito è riportato il codice di esempio:
<?php //crea area di memoria condivisa $shm_key = ftok(__FILE__, 'a'); $shm_id = shm_attach($shm_key, 1024, 0755); //var_dump($shm_id);die(); risorsa (4) di tipo (sysvshm) const SHARE_KEY = 1; $child_list = []; //aggiungi segnalatore $sem_id = ftok(__FILE__, 'b'); $signal = sem_get($sem_id); //risorsa di segnale (5) di tipo (sysvsem) for ($i = 0; $i < 3; $i++) { $pid = pcntl_fork(); exit("Fallo di fork!".PHP_EOL); elseif ($pid == 0) { } //Ottieni il semaforo sem_acquire($signal); if (shm_has_var($shm_id,SHARE_KEY)) { $count = shm_get_var($shm_id, SHARE_KEY); $count++; //Simulazione di elaborazione aziendale $sec = rand(1, 3); sleep($sec); shm_put_var($shm_id, SHARE_KEY, $count); } $count = 0; $sec = rand(1, 3); sleep($sec); shm_put_var($shm_id, SHARE_KEY, $count); } echo "processo figlio: ".getmypid()." sta scrivendo! Ora count è: $count ".PHP_EOL; //Rilascia il semaforo sem_release($signal); exit("processo figlio".getmypid()."fine".PHP_EOL); } $child_list[] = $pid; } } while (count($child_list) > 0) { foreach ($child_list as $key => $pid) { $status = pcntl_waitpid($pid, $status); if ($status > 0 || $status == -1) { unset($child_list[$key]); } } sleep(1); } $count = shm_get_var($shm_id, SHARE_KEY); echo " $count ".PHP_EOL; //Distruggi il semaforo sem_remove($signal); shm_remove($shm_id); shm_detach($shm_id);