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
No he entendido muy bien lo que quieres hacer, pero puedes buscar sobre la funcion usleep().
Saludos.
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
#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.