C/Visual C - Funcion bloqueante

 
Vista:
sin imagen de perfil

Funcion bloqueante

Publicado por Jorge (31 intervenciones) el 15/07/2016 08:55:30
Hola a todos:

Alguien sabe como se puede hacer una función bloqueante ? Es decir algo parecido a la función read() que se utilizan habitualmente en los sockets y que al invocarla el proceso se queda dormido ( sin consumir recursos ) y cuando hay algo que leer el proceso se despierta, lee y continua.

La otra opción es hacer un pool continuo de lecturas, pero eso consume recursos de sistema.

La opción de función bloqueantes es más optima.

¿ Alguien sabe como hacerlo ?

Muchas Gracias a todos

Un saludo
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil
Val: 296
Bronce
Ha mantenido su posición en C/Visual C (en relación al último mes)
Gráfica de C/Visual C

Funcion bloqueante

Publicado por agustin (272 intervenciones) el 17/07/2016 12:03:07
Podrías crear un bucle que termine con la condición deseada y dentro haces la lectura que desees y después un sleep de x milisegundos. Con eso no se satura y no consumirá prácticamente nada.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Funcion bloqueante

Publicado por jorge (31 intervenciones) el 17/07/2016 12:16:00
Hola:

Gracias por la respuesta.

Esa es la solucion que actualmente tengo implementada, pero no es la que busco. Además haciendo pruebas, y colocando diferentes tiempos de sleep, se puede apreciar que siempre se penaliza el consumo de CPU.

Para hacer un proceso óptimo, es necesario hacerlo de la forma que pregunto: algo que se "dispare" cuando es necesario y el resto de tiempo no consuma recursos.

Gracias de todas maneras.

Un saludo
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Funcion bloqueante

Publicado por Nacho (76 intervenciones) el 18/07/2016 09:09:35
Eso que llamas función bloqueante es sincronización de hilos. Cuando usas una función bloqueante lo que haces es suspender el hilo que llama esa función hasta que se produzca un evento.

Una manera de hacer eso es usar WaitForSingleObject, u otra función para sincronizar hilos.

El read de un socket es una función bloqueante, que no te sirve fuera de un socket. Otra función bloqueante es GetMessage. GetMessage bloquea un hilo hasta que recibe ese hilo un mensaje de Windows. Si tienes un hilo bloqueado con GetMessage lo desbloquearás mandando desde otro hilo un mensaje. Esa es la manera de hacerlo, no un chapucero Sleep.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Funcion bloqueante

Publicado por Jorge (31 intervenciones) el 18/07/2016 10:22:49
Hola:

Gracias por la respuesta.

Eso es lo que yo busco, pero acabo de mirar en internet sobre "WaitForSingleObject" y "GetMessage " y por lo que veo son funciones de Windows. Actualmente mi proceso trabaja en Linux y esto no lo puedo cambiar.

¿ Sabes cuales son las funciones análogas en linux ?


Por otro lado, en tu respuesta hablas de hilos, pero yo lo que necesito es enviar señales de un proceso a otro, no entre hilos del mismo proceso. ¿ Es esto posible ?.

Muchas Gracias

Un saludo
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Funcion bloqueante

Publicado por Nacho (76 intervenciones) el 18/07/2016 11:18:08
Por eso te he puesto " WaitForSingleObject, u otra función para sincronizar hilos". Como el foro era de vc pensé que podría ser para Windows.

Pero el sistema es el mismo. Se trata de sincronizar dos hilos. Funciones como GetMessage existen en Linux, pues el modo de funcionamiento es básicamente igual, a base de eventos. http://stackoverflow.com/questions/8592292/how-to-quit-the-blocking-of-xlibs-xnextevent. La ventaja de usarlo es que tienes gran parte del trabajo hecho.

Lo que tienes que hacer es empoyarte bien los mutex en Linux. Son propios del núcleo del sistema operativo, independientes de cualquier framework o añadido gráfico, así que no te encontrarás el problema del que hablan en la página de antes o en http://www.linuxquestions.org/questions/programming-9/getmessage-on-linux-282022/.

Un proceso es un objeto de núcleo que consta de unas cuantas estructuras y objetos, y entre otros, como mínimo, un hilo. No existe la comunicación entre procesos, ni puedes detener un proceso, ni sincronizar un proceso. Eso sólo puedes hacerlo con un hilo. Ese hilo puede ser de otro proceso o del mismo que ejecute tu código. Hasta qué punto puedes interactuar desde el hilo de un proceso en otro de otro proceso depende del sistema operativo. Windows es completamente permisivo, lo que tiene sus ventajas e inconvenientes, como todo. Es otra de las características que le hace más vulnerable a ataques.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Funcion bloqueante

Publicado por Chema (234 intervenciones) el 18/07/2016 20:46:02
--Un proceso es un objeto de núcleo que consta de unas cuantas estructuras y objetos, y entre otros, como mínimo, un hilo. No existe la comunicación entre procesos, ni puedes detener un proceso, ni sincronizar un proceso---

¿Estás seguro de lo que comentas?,

Yo creo que es totalmente al contrario de lo que comentas.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 296
Bronce
Ha mantenido su posición en C/Visual C (en relación al último mes)
Gráfica de C/Visual C

Funcion bloqueante

Publicado por agustin (272 intervenciones) el 19/07/2016 22:56:14
En windows se puede usar memoria compartida para comunicarse entre procesos.
Por otro lado, si son dos procesos diferentes ¿por qué no usar sockets o pipes?
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Funcion bloqueante

Publicado por jorge (31 intervenciones) el 26/07/2016 23:11:58
Hola:

Ante todo, gracias por la respuesta/s, pero... respecto a la ultima respuesta,:

¿ Que tiene de ventaja hacerlo con Socket, memoria compartida o pipes ? ¿ Como hago que el proceso uno se duerma y el proceso dos "despierte al proceso uno ?

Con Sockets, memoria compartida o pipes, sólo se me ocurre hacer un bucle infinito que chequee algo ( un byte, un bit,....algo ) y cuando detecte "algo" se salga de bucle y parezca que se ha despertado... pero no es así !!!! La realidad es que se habrán estado consumiendo recursos de CPU ( por pocos que sean ) que harán que el proceso no sea óptimo ni preciso

El hecho de que los equipos de hoy en día tengan muchos recursos, no significa que desarrollar algo que los malgasta, esté bien hecho.

Insisto, gracias por su ayuda.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Funcion bloqueante

Publicado por Nacho (76 intervenciones) el 27/07/2016 13:46:14
Un socket tiene una función bloqueante. Mientras no mandes algo desde otro hilo o desde otro ordenador no vuelve.

Cuando usas un socket para comunicar dos procesos dentro de un ordenador en realidad se usa memoria compartida. Si sólo se te ocurre usar un bucle usando memoria compartida es que no te has estudiado lo que te dije.

https://msdn.microsoft.com/es-es/library/windows/desktop/ms686360(v=vs.85).aspx

Ahí tienes un resumen de las funciones de sincronización de Windows. No creo que Linux tenga menos.

Con memoria compartida no tendrías más que usar una sección crítica. Una sección crítica es una zona de memoria con código o datos a los que puede acceder más de un hilo, y hay que controlar ese acceso. Parece que lo que tienes es un proceso con un hilo que lee el puerto com y quieres mandar algo a otro proceso cuando lea algo. Podrías declarar una variable en memoria compartida como sección crítica. En el proceso que lee tienes pillada esa sección crítica. Cuando entre algo por el com escribes lo entrado en esa variable y sueltas la sección crítica. En el otro proceso tienes un hilo suspendido pendiente de esa sección cítica. Cuando se encuentre esa zona liberada despierta y se encuentra en esa posición de memoria lo que haya escrito el otro proceso.

Me dicen mucho si veo todo siempre tan fácil. Esto lo he hecho tantas veces que sí, es fácil.

Por cierto, un proceso o sus hilos no despierta otro proceso o hilos. Un hilo dormido es un hilo al que el sistema operativo no asigna tiempo de cpu. En ningún momento la cpu va a procesar código de ese hilo. Sólo le asignará tiempo de cpu cuando se produzca el evento que está esperando, uno de los que habla la página que te he puesto antes.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

Funcion bloqueante

Publicado por Jorge (31 intervenciones) el 27/07/2016 15:08:46
Hola:

Gracias por la respuesta. Tomo nota de lo que me dices e intentaré ver si me sirve.

Un saludo
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Funcion bloqueante

Publicado por Tom (619 intervenciones) el 27/07/2016 15:09:14
Como ya te comentan (varias veces) un proceso no se bloquea a sí mismo ni a otros. Es función del S.O. asignar o no tiempo de CPU a los procesos.
Así que, en principio, tu programa será tan "bueno" ahorrando CPU como el S.O. se lo permita.
Para que el S.O ponga a tu proceso a dormir, lo que se suele hacer es usar read() de algún descriptor abierto en modo bloqueante (fichero, pipe, socket, ...) de modo que el S.O. no despertará a tu proceso hasta que read() tenga algo que devolver (algún otro proceso escriba) o se produzca algún error.
Dependiendo de lo que quieras hacer (no lo dices) puedes combinar este método con poll() o select().

Y si no quieres usar read() puedes usar también un semáforo (un semáforoPOSIX), sin más (a grandes rasgos un programa espera dormido a que el semáforo se abra, y otro programa lo abre o cierra).
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Claudio

Funcion bloqueante

Publicado por Claudio (2 intervenciones) el 06/09/2016 18:40:36
Si no querés que este continuamente leyendo no te conviene ponerle un timer? O una función que lea la entrada de datos para ver si hay algo nuevo. El tema en C es que es lineal. No es como la programación orientada a objetos que podes tener varios objetos funcionando a la vez y uno que controle al otro.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar