일반적으로 Drupal DB 세마포어 테이블의 목적은 무엇입니까


9

IPC 프로그래밍에서 세마포어의 목적을 이해하지만이 표의 목적에 대한 좋은 설명을 찾지 못했습니다.

답변:


11

세마포어 테이블은 Drupal에서 기본적으로 구현 된 잠금 메커니즘 에서 사용됩니다 . 프로그래밍에서 볼 수있는 일반적인 잠금 메커니즘과 다르지 않습니다 . 충돌이나 경쟁 조건을 피하기 위해 작업 이 이미 진행 중인지 확인하는 데 값이 사용됩니다 . 차이점은 일반적으로 잠금은 파일이고 Drupal은 데이터베이스에서 행을 사용한다는 것입니다.

실제로, 잠금 메커니즘은 잠금을 획득 ( lock_acquire())하거나 잠금이 해제되기를 기다리는 기능 ( lock_wait())을 갖는다. 두 경우 모두 세마포어 데이터베이스가 사용됩니다.

// 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;

Drupal에서 다른 사용자가 동일한 페이지를 요청할 수 있으므로 다른 스레드 또는 프로세스가 동시에 동일한 코드를 실행할 수 있습니다. 코드가 데이터베이스 테이블을 업데이트하는 등의 경우 문제가 발생할 수 있습니다. 잠금을 사용하면이를 방지 할 수 있습니다.

데이터베이스 테이블이 사용되는 이유는 Drupal이 데이터베이스 엔진을 작동시켜야하기 때문입니다. 잠금 메커니즘에도 데이터베이스 테이블을 사용하면 요구 사항을 줄일 수 있습니다. 잠금 메커니즘은 APCu 확장을 사용하여 구현할 수 있으며 올바르게 기억하면 모듈이 있습니다.


훌륭한 답변입니다. 그러나 세마포어 테이블은 DB 엔진의 기본 잠금 메커니즘과 분리되어 있습니다 (예 : mysql).
Mike

2
세마포어 테이블은 Drupal에서 작성하고 사용합니다. 데이터베이스 엔진에서 사용되지 않습니다.
kiamlaluno

6

@kiamlaluno의 답변은 완전하고 완벽합니다. 그러나 drupal의 세마포어를 사용하여 db 잠금의 개념 / 사용법을 설명하는 데 중점을두고 있다고 생각합니다.

나는 다시 영업에 가까워 질 것이다.

세마포어 테이블의 목적은 다음과 같습니다 (세마포어 테이블 작성 설명에 설명 된대로).

Drupal 변수로 저장 될 수없는 세마포어, 잠금, 플래그 등을 보유하기위한 테이블입니다.

따라서 해당 테이블의 목적은 단순한 DB 잠금 메커니즘 이상이며 (지금까지 해당 의견에서 이해할 수 있음) 변수 캐싱을 피하기위한 기술적 요구 사항도 해결합니다.

NB : 내가 잘못 알고 있다면이 주제에 대해 더 많은 전문 지식을 가진 사람이 기꺼이 시정 할 것입니다. 건배!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.