Pregunta

Tengo un programa Perl CGI que se ejecuta bajo mod_perl. Dentro del programa, me gustaría evitar que un recurso acceda por múltiples procesos al mismo tiempo.

# Semaphore Initialization Code
# 10023 is unique id, and this id will be same across different apache process.
# 1, Only one semaphore being created.
# 0722, as all process will be execute under apache account. Hence, they will all having '7' privilege.
my $sem = new IPC::Semaphore(10023, 1, 0722 | IPC_CREAT); # Code(1)
# Set 0th (one and only one) semaphore's value to 1, As I want to use this semaphore as mutex.
$sem->setval(0, 1);                                       # Code(2)

El problema es:

  1. ¿Cómo puedo hacer que el Código (1) cree un nuevo semáforo SOLO cuando el semáforo si la identificación 10023 nunca se ha creado antes, ya sea por el mismo proceso u otros procesos?
  2. ¿Cómo puedo ejecutar el Código (2) SOLO la primera vez que creo el semáforo con 10023 id? Un semáforo solo se inicializará UNA VEZ.

Otro enfoque es crear un archivo vacío para bloquearlo. Sin embargo, esto terminará teniendo miles de archivos temporales. texto del enlace

¿Fue útil?

Solución

Agregar el indicador IPC_EXCL hace que el semget subyacente cree un nuevo semáforo o falle. Puede usar esto para obtener el efecto que desee.

Esto debería funcionar para usted:

#Attempt to create (but not get existing) semaphore
my $sem = IPC::Semaphore->new(10023, 1, 0722 | IPC_CREAT | IPC_EXCL);
if ($sem) {
    #success, semaphore created, proceed to set.
    print "new semaphore\n";
    $sem->setval(0, 1);
}
else {
    #obtain the semaphore normally
    print "existing semaphore\n";
    $sem = IPC::Semaphore->new(10023, 1, 0722); #no IPC_CREAT here
    die "could not obtain semaphore?" unless $sem;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top