Como hacer que un bucle se ejecute durante X milisegundos en linux

Iniciado por Patofet, 17 Agosto 2012, 20:59 PM

0 Miembros y 2 Visitantes están viendo este tema.

Patofet

Hola, voy directamente al grano, estoy intentando ejecutar un bucle durante X milisegundos en linux, en windows lo he conseguido hacer así:

 
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include "funciones.h"

 char iesperaMirandoTecla(int milisegundos){ //Hace esperar "milisegundos" milisegundos mientras va mirando por teclado si se esta pulsando alguna tecla
       char caracter='\0';
       int contador=0;
       clock_t final=clock()+(milisegundos*(CLOCKS_PER_SEC/1000));
       init_keyboard();
       while(( clock() < final) && (caracter=='\0')){
           if(kbhit()){
               caracter = readch();
               printf("\b ");
           }
           esperaMilisegundos(1);
           contador++;
       }
       close_keyboard();
       return caracter;
   }


pero en linux pongo lo mismo y no funciona, en principio todo(vale casi todo lo del teclado no) esta en ANSI C y en linux no me funciona y no logro entender y no logro saber el porque ..., ¿alguien tiene alguna idea?

Gracias de antemano

P:D: Aclaración: Seria question de antes de entrar al bucle preguntarle al sistema la "hora" y luego a cada aliteracion del bucle mirar la hora que es y mirar si se ha pasado del tiempo

0xDani

No he entendido muy bien lo que quieres hacer, pero puedes buscar sobre la funcion usleep().

Saludos.
I keep searching for something that I never seem to find, but maybe I won't, because I left it all behind!

I code for $$$
Hago trabajos en C/C++
Contactar por PM

Patofet

no, con usleep() no hay forma de controlar que el bucle se ejecute durante exactamente X milisegundos, ya que las funciones que leen por teclado y estas cosas hacen "perder el tiempo" al procesador. Seria question de antes de entrar al bucle preguntarle al sistema la "hora" y luego a cada aliteracion del bucle mirar la hora que es y mirar si se ha pasado del tiempo

Foxy Rider


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <termios.h>
#include <unistd.h>


char kbPeek(int msTimeOut)
{
   /* Antiguo y nuevo estado de la terminal con y sin modo ICANON */
   struct termios prevTIOS;
   struct termios newTIOS;

   /* Agregamos el timeout a una estructura timeval */
   struct timeval tvTimeout;
       tvTimeout.tv_usec = msTimeOut * 1000; /* mili -> micro */

   /* Armamos un fd_set con STDIN para pasarlo a select() */
   fd_set readSet;
       FD_ZERO(&readSet);
       FD_SET(STDIN_FILENO,&readSet);


   /* Guardamos el termios original con el modo canonico levantado
    * y lo desactivamos, pasando a modo RAW */

   tcgetattr(0,&prevTIOS);
   memcpy(&newTIOS,&prevTIOS,sizeof(struct termios));

   cfmakeraw(&newTIOS);
   tcsetattr(0,TCSANOW,&newTIOS);

   /* Pedimos a select que revise el descriptor de fichero STDIN
      esperando hasta determinado tiempo puesto en tvTimeOUT */
   int retval = select(1,&readSet,0,0,&tvTimeout);

   if ( retval == -1)
       perror("select()"); /* Algo salio mal */

   else if (retval == 0)
       return 0; /* No paso nada */

   /* Si paso algo ... usemos read() para pedir un caracter */
   char peekedChar;
       read(STDIN_FILENO,&peekedChar,1);

   /* Volvemos al modo canonico y retornamos valor */
   tcsetattr(0,TCSANOW,&prevTIOS);

   return peekedChar;
}



int main(int argc, char *argv[])
{
   /* Aca guardamos cuanto queremos esperar y el caracter en cuestion */
   int msTimeout = 900;
   char readValue;

   /* Usamos \r\n por que solo dentro de kbPeek() estamos en modo RAW */
   printf("Esperando %dms una tecla ...\r\n",msTimeout);

   /* Largamos kbPeek*/
   readValue = kbPeek(msTimeout);

   /* Mostramos */
   printf("Leido : %c \r\n", readValue );
   
   return EXIT_SUCCESS;
}



No recuerdo cuan portable es termios (dentro de *nix, en teoría es algo *portable*), though ... de todas maneras, si tenés un código Windows, vas a tener que usar preprocesador te guste o no, así que la portabilidad es lo de menos si podés agregar diferentes implementaciones vía preprocessor.

Saludos.