es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Sincronizar con sigev_notify_function()

Me gustaría leer (asincrónicamente) BLOCK_SIZE bytes de un archivo, y los BLOCK_SIZE bytes del segundo archivo, imprimiendo lo que se ha leído en el buffer tan pronto como el respectivo buffer se haya llenado. Permítanme ilustrar lo que quiero decir:

// en main()
int infile<em>fd = open(infile</em>name, O<em>RDONLY); // agregar verificación de errores
int maskfile</em>fd = open(maskfile<em>name, O</em>RDONLY); // agregar verificación de errores
char* buffer<em>infile = malloc(BLOCK</em>SIZE); // agregar verificación de errores
char* buffer<em>maskfile = malloc(BLOCK</em>SIZE); // agregar verificación de errores
struct aiocb cb<em>infile;
struct aiocb cb</em>maskfile;
// configurar los bloques de control AIO
memset(&cb<em>infile, 0, sizeof(struct aiocb));
cb</em>infile.aio<em>fildes = infile</em>fd;
cb<em>infile.aio</em>buf = buffer<em>infile;
cb</em>infile.aio<em>nbytes = BLOCK</em>SIZE;
cb<em>infile.aio</em>sigevent.sigev<em>notify = SIGEV</em>THREAD;
cb<em>infile.aio</em>sigevent.sigev<em>notify</em>function = print<em>buffer;
cb</em>infile.aio<em>sigevent.sigev</em>value.sival<em>ptr = buffer</em>infile;

<pre><code>memset(&amp;cb_maskfile, 0, sizeof(struct aiocb));
cb_maskfile.aio_fildes = maskfile_fd;
cb_maskfile.aio_buf = buffer_maskfile;
cb_maskfile.aio_nbytes = BLOCK_SIZE;
cb_maskfile.aio_sigevent.sigev_notify = SIGEV_THREAD;
cb_maskfile.aio_sigevent.sigev_notify_function = print_buffer;
cb_maskfile.aio_sigevent.sigev_value.sival_ptr = buffer_maskfile;
</code></pre>

<code>
y la función `print_buffer()` se define de la siguiente manera:
</code>
void print<em>buffer(union sigval sv)
{
    printf("%s\n", <strong>func</strong>);
    printf("dirección del buffer: %p\n", sv.sival</em>ptr);
    printf("buffer: %.128s\n", (char*)sv.sival<em>ptr);
}
<code>
Al final del programa realizo la limpieza habitual, es decir:
</code>
// limpieza
close(infile</em>fd); // agregar verificación de errores
close(maskfile<em>fd); // agregar verificación de errores
free(buffer</em>infile);
printf("buffer<em>inline liberado\n");
free(buffer</em>maskfile);
printf("buffer_maskfile liberado\n");
Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para solucionar este problema, puedes utilizar un mecanismo de sincronización como un mutex para asegurarte de que el buffer no se libere antes de que print_buffer haya terminado su trabajo. Así es cómo puedes modificar el código:

    1. Declarar un mutex:
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    
    1. Bloquear el mutex antes de llamar a print_buffer:
    void print_buffer(union sigval sv)
    {
        printf("%s\n", __func__);
        printf("address del buffer: %p\n", sv.sival_ptr);
        pthread_mutex_lock(&mutex);
        printf("buffer: %.128s\n", (char*)sv.sival_ptr);
        pthread_mutex_unlock(&mutex);
    }
    
    1. Desbloquear el mutex una vez que el buffer haya sido impreso:
    // en main()
        ...
        cb_infile.aio_sigevent.sigev_notify_function = print_buffer;
        cb_infile.aio_sigevent.sigev_value.sival_ptr = buffer_infile;
        cb_maskfile.aio_sigevent.sigev_notify_function = print_buffer;
        cb_maskfile.aio_sigevent.sigev_value.sival_ptr = buffer_maskfile;
        ...
    // limpiar
        ...
        pthread_mutex_destroy(&mutex);
    

    De esta manera, la función print_buffer bloqueará cualquier intento de liberar el buffer hasta que haya completado su trabajo. Ten en cuenta que también debes destruir el mutex al final del programa.

Comments are closed.