2011-05-31 11 views
7

He intentado utilizar los archivos temporales:cerraduras de archivos para Linux

char *temp = tempnam(NULL, "myapp_"); 
printf("Tempname: %s", temp)  // Prints /tmp/myapp_random 
while (1) { } 

Pero cuando compruebo /tmp (mientras que la aplicación aún está en marcha), el myapp_random no está allí!

En cuanto a usar File Locks, no puedo entenderlo bien, traté de mirar <fcntl.h> pero parece centrarse en bloqueos en partes específicas de un archivo. Solo quiero utilizar el archivo por completo como un bloqueo (por eso prefiero probar el enfoque de archivo temporal).

¿Alguna idea?

+0

Esto parece un duplicado de http://stackoverflow.com/questions/800730/cc-how-to-tell-if-a-program-is-already -running –

+0

@Richard, esa pregunta fue específicamente para Windows. Éste es casi seguro que un UNIXy de tipo uno ya que (1) 'tempnam' está desfasada y en VC2005, (2) la referencia del código'/tmp/myapp_random' que no es realmente una cosa de Windows. – paxdiablo

Respuesta

9

tempnam no crear el archivo, simplemente le da un nombre de archivo que no existía en el momento que lo llamó.

Aún tiene que crear el archivo usted mismo y, por lo tanto, todavía tiene la condición de carrera que otro proceso puede colarse y crearlo antes que usted.

En realidad no quiere utilizar tempnam ya que le dará a cada proceso de su propio nombre de archivo y que será capaz de ejecutar simultáneamente. Lo que necesita es un nombre de archivo fijo (como /tmp/myapp.lck por ejemplo) que se abre cada proceso y luego intenta flock.

Es mejor que con flock para un archivo de bloqueo, fcntl le dará un grano más fino de bloqueo (partes de archivos), pero eso no es realmente un requisito aquí.

El código se ejecutaría algo como esto:

if ((mylockfd = open ("/tmp/myapp.lck", O_CREAT | O_RDWR, 0666)) < 0) { 
    // error, couldn't open it. 
    return; 
} 
if (flock (mylockfd, LOCK_EX | LOCK_NB) < 0) { 
    // error, couldn't exclusive-lock it. 
    return; 
} 
: 
// Weave your magic here. 
: 
flock (mylockfd, LOCK_UN); 

Eso probablemente necesita un poco de trabajo, pero debe ser un buen comienzo. Una solución más generalizada sería algo así como:

int acquireLock (char *fileSpec) { 
    int lockFd; 

    if ((lockFd = open (fileSpec, O_CREAT | O_RDWR, 0666)) < 0) 
     return -1; 

    if (flock (mylockfd, LOCK_EX | LOCK_NB) < 0) { 
     close (lockFd); 
     return -1; 
    } 

    return lockFd; 
} 

void releaseLock (int lockFd) { 
    flock (lockFd, LOCK_UN); 
    close (lockFd); 
} 

// Calling code here. 

int fd; 
if ((fd = acquireLock ("/tmp/myapp.lck")) < 0) { 
    fprintf (stderr, "Cannot get lock file.\n"); 
    return 1; 
} 

// Weave your magic here. 

releaseLock (fd); 
+0

No me preocupa esta condición de carrera ... la creación de aplicaciones es realizada por un ser humano. Además, la mayoría de las veces, la aplicación no se cierra correctamente (es decir, se bloquea o Ctrl + C) ... así que si abro el archivo en "r", no parece crear en el disco todavía, pero si Lo abro en "w", lo crea pero cuando mi programa falla, el archivo todavía está allí. ¿Alguna solución para esto? Gracias – user657178

+0

¡Un millón de gracias! YAY: D the 0_CREAT | 0_RDWR, 0666 funcionó ... Creo que antes solo tenías 0_CREAT pero esto es exactamente lo que necesitaba. Muchas gracias :) – user657178

Cuestiones relacionadas