En la programación de sockets, ¿por qué la llamada ‘aceptar’ es una llamada de bloqueo?

No, no es inherentemente bloqueo. Solo se bloquea si la toma de escucha que le pasó no se marcó como no bloqueante.

¿Una llamada de bloqueo no desperdiciaría recursos innecesariamente hasta que algún cliente intente conectarse?

A diferencia de DOS, todos los sistemas operativos tipo Unix son multitarea . Si un proceso en particular realiza una llamada al sistema que bloquea, el núcleo simplemente lo pone en suspensión y reanuda la ejecución de algún otro proceso que no esté en estado de bloqueo. No se desperdician recursos innecesariamente.

Esta es la razón por la cual el modo predeterminado de todas las operaciones de E / S bajo sistemas operativos tipo Unix es el bloqueo: simplifica la lógica del código en la mayoría de los casos (“mi conexión aún no está aquí; el núcleo me pondrá a dormir y me despertará cuando llegue) , y continuaré como de costumbre, no se preocupe “), mientras se garantiza la máxima utilización de todos los recursos.

Si está escribiendo una aplicación C10K, o de lo contrario necesita que su E / S no se bloquee por cualquier razón, puede marcar sus descriptores de E / S como no bloqueantes , pero luego tendrá que volver para verificarlos y más, que es exactamente el tipo de desperdicio del que te estás quejando.

O bien, puede usar llamadas del sistema como select, poll y epoll en una gran cantidad de descriptores de bloqueo normales, que se bloquearían hasta que cualquiera de sus descriptores esté listo para hacer cualquier E / S que desee realizar. Esto ayuda a evitar una situación en la que está bloqueando un descriptor mientras que otros 20 están “listos para funcionar”.

Aceptar no siempre es una llamada de bloqueo. Si el zócalo está configurado para no bloquear, aceptar volverá con EAGAIN o EWOULDBLOCK. La forma de usar aceptar en servidores sin bloqueo es colocar el servidor fd en select / epoll /. El servidor fd recibirá un evento si hay alguna conexión nueva.

Ver aceptar (2): aceptar conexión en el zócalo

Todas las operaciones de entrada y salida son fundamentalmente de bloqueo o síncronas, ya que debe esperar a que los datos o el proceso se completen y devuelvan un valor. Si el lenguaje de programación le proporciona una opción de llamada asincrónica o sin bloqueo, esencialmente utilizará otro hilo en segundo plano y una vez que la llamada real regrese, activará un evento o llamará a un método de devolución de llamada.

Ejemplo: en c #, puede encontrar tanto tipos de llamadas como Accept () que está bloqueando y BeginAccept () que no está bloqueando. Tendrá que crear y administrar su propio hilo de fondo para usar la llamada Accept () mientras puede usar BeginAccept () y c # usará un hilo de fondo para hacerlo.