Rozumiem cel semaforów w programowaniu IPC, ale nie znajduję dobrego - ani żadnego - wyjaśnienia co do tego celu tabel.
Tabela semaforów jest używana z mechanizmu blokującego implementowanego domyślnie z Drupal. Nie różni się od zwykłego mechanizmu blokowania widocznego w programowaniu: Wartość służy do sprawdzenia, czy operacja jest już w toku, aby uniknąć konfliktów lub warunków wyścigu. Różnica polega na tym, że zwykle zamek jest plikiem, a Drupal używa wiersza w bazie danych.
W rzeczywistości mechanizm blokujący ma funkcje uzyskiwania blokady ( lock_acquire()
) lub czekania na zwolnienie blokady ( lock_wait()
). W obu przypadkach używana jest baza semaforów.
// lock_acquire()
// Optimistically try to acquire the lock, then retry once if it fails.
// The first time through the loop cannot be a retry.
$retry = FALSE;
// We always want to do this code at least once.
do {
try {
db_insert('semaphore')
->fields(array(
'name' => $name,
'value' => _lock_id(),
'expire' => $expire,
))
->execute();
// We track all acquired locks in the global variable.
$locks[$name] = TRUE;
// We never need to try again.
$retry = FALSE;
}
catch (PDOException $e) {
// Suppress the error. If this is our first pass through the loop,
// then $retry is FALSE. In this case, the insert must have failed
// meaning some other request acquired the lock but did not release it.
// We decide whether to retry by checking lock_may_be_available()
// Since this will break the lock in case it is expired.
$retry = $retry ? FALSE : lock_may_be_available($name);
}
//lock_may_be_available()
$lock = db_query('SELECT expire, value FROM {semaphore} WHERE name = :name', array(':name' => $name))->fetchAssoc();
if (!$lock) {
return TRUE;
}
$expire = (float) $lock['expire'];
$now = microtime(TRUE);
if ($now > $expire) {
// We check two conditions to prevent a race condition where another
// request acquired the lock and set a new expire time. We add a small
// number to $expire to avoid errors with float to string conversion.
return (bool) db_delete('semaphore')
->condition('name', $name)
->condition('value', $lock['value'])
->condition('expire', 0.0001 + $expire, '<=')
->execute();
}
return FALSE;
W Drupal różni użytkownicy mogą żądać tej samej strony, co oznacza, że różne wątki lub procesy mogą wykonywać ten sam kod w tym samym czasie. Może to powodować problemy, gdy kod na przykład aktualizuje tabelę bazy danych. Korzystanie z zamków jest sposobem na uniknięcie tego, co może powodować problemy.
Powodem użycia tabeli bazy danych jest po prostu to, że Drupal wymaga silnika bazy danych do działania; użycie tabeli bazy danych również dla mechanizmu blokującego jest sposobem na zmniejszenie wymagań. Mechanizm blokujący można również wdrożyć za pomocą rozszerzenia APCu, a jeśli dobrze pamiętam, moduł to robi.
Odpowiedź od @kiamlaluno jest kompletna i idealna. Ale myślę, że koncentruje się na (genialnym) wyjaśnieniu pojęcia / zastosowania blokowania db przy użyciu semaforów drupala.
Z kolei zaryzykuję zbliżenie się do PO:
Celem tabeli semaforów jest (jak opisano w opisie tworzenia tabeli semaforów):
Tak więc celem tej tabeli jest coś więcej niż tylko mechanizmy blokowania db (jak do tej pory rozumiem z tego komentarza), a także spełnia on techniczny wymóg unikania buforowania zmiennych.
NB: Z przyjemnością poprawię je ktoś, kto ma większą wiedzę na ten temat, jeśli się mylę. Twoje zdrowie!
źródło