2011-03-07 10 views
12

Tengo una aplicación multiproceso C++ que utiliza tuberías posix para realizar comunicaciones entre hilos de manera eficiente (por lo que no tengo que volverme loco con bloqueos).Establecer tamaño de búfer de tubería

He configurado la operación de escritura como no bloqueante, por lo que el escritor obtendrá un error si no hay suficiente espacio en el búfer para escribir.

if((pipe(pipe_des)) == -1) 
    throw PipeException(); 

int flags = fcntl(pipe_des[1], F_GETFL, 0); // set write operation non-blocking 
assert(flags != -1); 
fcntl(pipe_des[1], F_SETFL, flags | O_NONBLOCK); 

Ahora me gustaría que para establecer el tamaño del búfer de tubería a un valor personalizado (una palabra en el caso específico).

He buscado en Google, pero no he podido encontrar nada útil. ¿Hay alguna manera (posiblemente compatible con posix) para hacerlo?

Gracias

Lorenzo

PS: Estoy bajo Linux (si puede ser útil)

+1

Este es un uso totalmente inapropiado de assert(), a menos que su programa solo se ejecute en plataformas para las cuales fcntl() nunca tenga un error. –

+0

Creo que debería aprender a usar primitivas de sincronización. Usar una tubería aumentará la sobrecarga aproximadamente 100 veces, y parece que no puede lograr lo que desea de todos modos. –

+0

Sé cómo usar primitivas de sincronización :) En realidad, también tengo una versión que usa primitivas de sincronización ... En cuanto a los resultados de las pruebas, la versión con pipas es al menos más rápida que la de sincronización (en algunos casos, las pipas son velocíperas ...) – Zeruel

Respuesta

12

Como mencionas que estás en Linux y no te molesta la no portabilidad, te puede interesar el manipulador de descriptores de archivos F_SETPIPE_SZ, disponible desde Linux 2.6.35.

int pipe_sz = fcntl(pipe_des[1], F_SETPIPE_SZ, sizeof(size_t)); 

Encontrará que pipe_sz == getpagesize() después de esa llamada, ya que el búfer no puede hacerse más pequeño que el tamaño de página del sistema. Ver fcntl(2).

3

Busqué en Google "tamaño de búfer de canalización Linux" y tengo this as the top link. Básicamente, el límite es de 64 Kb y está codificado.

No estoy seguro de por qué está tratando de establecer el límite inferior, me parece una idea extraña. Si desea que el escritor espere hasta que el lector haya procesado lo que ha escrito, debe usar una tubería en la otra dirección para que el lector le devuelva un ack.

+1

Estoy enviando tareas a través de la tubería. Lo que quiero es tener un grado de asincronía que se pueda configurar a través de un parámetro pasado a la aplicación. Creo que debería ser una solución eficiente incorporar este comportamiento en la tubería sin tener que seguir la pista con infos y acks adicionales ... – Zeruel

+0

La conclusión es que no puede hacerlo de la manera que desee. – JeremyP

+0

Ok, gracias :) – Zeruel

2

Puede usar un área de memoria compartida (similar al Sistema V) de dos palabras, una para enviar datos y la otra para recibir datos, e implementar sus tuberías con ellas. otras soluciones, como puede encontrar previamente, se trata de recompilar el núcleo como le gustaría tener, pero no es el caso, supongo.

Ciao!

Cuestiones relacionadas