• Sábado 16 de Noviembre de 2024, 11:10

Autor Tema:  dormir la ejecución de una hebra  (Leído 2327 veces)

acs

  • Nuevo Miembro
  • *
  • Mensajes: 1
    • Ver Perfil
dormir la ejecución de una hebra
« en: Jueves 10 de Octubre de 2002, 11:31 »
0
Estoy usando la función Sleep para dormir la ejecucón de una hebra durante unos milisegundos, el problema es la precisión de la función, que me duerme la hebra más del tiempo que yo deseo.
Supongo que esto se debe a que una vez que se duerme se pasa la ejecución a otra hebra y tarda demasiado en volver, pero no se como solucionar este problema.

DarkArchon

  • Nuevo Miembro
  • *
  • Mensajes: 4
    • Ver Perfil
Re: dormir la ejecución de una hebra
« Respuesta #1 en: Miércoles 18 de Febrero de 2004, 08:21 »
0
En windows nada es preciso. Obiamente estas usando ::Slep pero sino proba hacer un while con ::GetTickCount

Esa api te devuelve los ticks desde que inicio windows hasta el momento de ser llamado.

Por ahi lo que debes hacer, es tomar el tiempo (ticks) en un punto de tu hebra y luego volverlo a tomar en el momento que se deberia dormir (es mas rapido que sleep). Obiamente si restar el 2do numero del primero tenes el retraso, o tiempo que tomo tu programa en ejecutar el codigo entre medio de las dos llamadas (en milisegundos).

Igual acordate que en dos procesadores distintos puede variar el tiempo de retraso, y no seria portable tu soft.

te pongo un ejemplo

DWORD ts;

ts= ::GetTickCount();

//codigo, codigo

while(::GetTickCount() - ts > 1000);    //genera un retraso  
                                                        //  si el codigo ha demorado menos de 1seg
1seg= 1000 ms                                  //hasta cumplir el segundo

By: THE SPECIALIST
- el mundo sigue girando por la inercia -

shephiroth

  • Miembro activo
  • **
  • Mensajes: 30
    • Ver Perfil
Re: dormir la ejecución de una hebra
« Respuesta #2 en: Miércoles 18 de Febrero de 2004, 11:03 »
0
Buenas. Si quieres seguir trabajando con el sleep, y lo que te interesa es un bucle al segundo puedes hacer algo como esto:

Thread * mithread;
...
mithread = new Thread(new ThreadStart(this,this->tufuncion);
...
mithread->start();

eso será la creacion, ahora vamos a la funcion:

void tufuncion()
{
int mili;
int seg;
mili = System::DateTime::get_Millisecond();
while ('el thread se tenga que ejecutar')
{
//aqui haces una vuelta
...
//y ahora para controlar la siguiente vuelta
mithread->sleep(900);//lo mandamos dormir 900 milisegundos, asi tendremos una aproximacion mas certera
seg = System::DateTime::get_Millisecond();
if (seg>mili) mithread->sleep(mili+1000-seg-2);
else mithread->sleep(seg-mili-2);
mili = System::DateTime::get_Millisecond();
}
...
}

El codigo me parece es bastante sencillo. Lo unico son los 2 milisegundos que descansa de menos. En principio es por el tiempoque tarde en volver arriba del while.

Si quisieses conseguir un código portable, y 100% seguro (mejor dicho, 99,9999&) antes del while deberías comprobar cuantos milisegundos tarda en hacer lo que sea. Es decir, la funcion sería algo como:

void mifuncion(){
int mili;
int seg;
int tiempoinvertido;
//primero controlamos el tiempo que tarda
mili = System::DateTime::get_Millisecond();
seg = System::DateTime::get_Millisecond();//en el bucle lo hace con mili
tiempoinvertido=System::DateTime::get_Millisecond();
if (tiempoinvertido<mili) tiempoinvertido=tiempoinvertido+1000-mili;
else tiempoinvertido=tiempoinvertido-mili;
//ahora lo hacemos igual que antes, contando con esta variable
while ('el thread se tenga que ejecutar')
{
//aqui haces una vuelta
...
//y ahora para controlar la siguiente vuelta
mithread->sleep(900);//lo mandamos dormir 900 milisegundos, asi tendremos una aproximacion mas certera
seg = System::DateTime::get_Millisecond();
if (seg<mili) mithread->sleep(seg+1000-mili-tiempoinvertido);
else mithread->sleep(seg-mili-tiempoinvertido);
mili = System::DateTime::get_Millisecond();
}
...
}

Algo asi podría resultar bastante portable xDD. Aunque dependiendo de lo que quieras puedes hacer un bucle un poco diferente y comprobar todo el rato la hora, y a cada cambio de segundo hacer lo que quieras. Yo tengo un programa que para no crear un reloj interno funciono con el de windows. Los sleep los tengo cada 100 milisegundos en principio, aunque esa cantidad la voy cambiando en tiempo de ejecucion dependiendo de la cantidad de milisegundos que queden para pasar de segundo (es decir, siempre hago 10 vueltas xDD)

Espero q te sirva, suerte ^_^