2010-04-21 39 views
12

Necesito mi proceso primario y secundario para que ambos puedan leer y escribir la misma variable (de tipo int) por lo que es "global" entre los dos procesos.C - tenedor() y memoria compartida

Supongo que esto usaría algún tipo de comunicación de proceso cruzado y tendría una variable en un proceso que se está actualizando.

Hice un Google e IPC rápidos y aparecen varias técnicas, pero no sé cuál es la más adecuada para mi situación.

¿Qué técnica es mejor y podría proporcionar un enlace a un tutorial de noobs para ella.

Gracias.

Respuesta

15

Puesto que usted está mencionando el uso de tenedor(), supongo que usted está viviendo en un * nix-Sistema

De Unix.com

La principal manera de compartir datos entre Los procesos que utilizan UNIX IPC son :

(1) Memoria compartida;

(2) de sockets:

Hay otras IPC UNIX incluyendo

(3) colas de mensajes.

(4) semáforos;

(5) Señales.

Su mejor opción (para IPCs) es utilizar segmentos de memoria compartida , en función de su publicación . Es posible que necesite usar los semáforos para asegurarse de que las operaciones de memoria compartida sean atómicas.

Un tutorial sobre la bifurcación y la memoria compartida es el cobertizo dev:

http://forums.devshed.com/c-programming-42/posix-semaphore-example-using-fork-and-shared-memory-330419.html

otra descripción más detallada de la utilización de múltiples hilos (si appilcable para su aplicación) se puede encontrar aquí:

https://computing.llnl.gov/tutorials/pthreads/

+0

Fui con memoria compartida al final. – Cheetah

+2

Texto sospechosamente similar aquí (¿desea vincular para obtener un crédito?): Http://www.unix.com/programming/857-fork-ipc.html – sje397

+0

@ sje397: Gracias por señalarme el fracaso de la cita – sum1stolemyname

4

Si necesita compartir memoria, quizás usar hilos en lugar de procesos sería una mejor solución?

+0

Su una misión para la universidad. Tienes que usar fork() específicamente – Cheetah

2

Una variante que utilicé recientemente de memoria compartida es abrir un mmap antes de bifurcar. Esto evita ciertas restricciones de la API compartida. No tiene un límite de tamaño (el rango de direcciones es el límite), no necesita generar la clave de ese archivo absoluto. Aquí un ejemplo de cómo lo hice (me he dejado la comprobación de errores en aras de la brevedad)

ppid = getpid(); 
shm_size = ...; 

char *tmpFile = tempnam(NULL, "SHM_"); /* Generate a temp file which is virtual */ 

/* Before we fork, build the communication memory maps */ 
mm = open(tmpFile, O_RDWR|O_CREAT|O_TRUNC, 0664)); /* Create the temp file */ 
ftruncate(mm, shm_size);        /* Size the file to the needed size, on modern Unices it's */ 
                 /* a sparse file which doesn't allocate anything in the file system */ 

/* The exact type of comm_area left to the implementer */ 
comm_area *pCom = (comm_area *)mmap(NULL, shm_size, PROT_READ|PROT_WRITE, MAP_SHARED, mm, 0); 
if(pCom == (comm_area*)MAP_FAILED) handle_error(); 
close(mm);        /* We can close the file, we won't access it via handle */ 
unlink(tmpFile);       /* We can also remove the file so even if we crash we won't let corpses lying */ 
free(tmpFile); 

/* Initialise some shared mutexes and semaphores */ 
pthread_mutexattr_t mattr; 
pthread_mutexattr_init(&mattr); 
pthread_mutexattr_setpshared(&mattr, PTHREAD_PROCESS_SHARED); 
pthread_mutex_init(&pCom->stderr_mutex, &mattr);   

/* nSonAsked, global variable with the number of forked processes asked */ 
for(nSon=0; nSon<nSonsAsked; nSon++) { 

    printf("Setup son #%.2u ",nSon+1); 
    /* Initialize a semaphore for each child process */ 
    sem_init(&pCom->sem_ch[nSon], USYNC_PROCESS, 0); 
    if(fork() == 0 { 
    ... /* do child stuff*/ 
    return; 
    } 
    /* Father, cleans up */ 
    pthread_mutexattr_destroy(&mattr); 
    ... 
    return; 
Cuestiones relacionadas