interrumpir bucle java

Bocasucia

como pueod interrumpir la ejecucion de un bucle en java cuando pase un numero determinado de segundos aunke el bucle se bloquee debido a la entrada de datos por teclado???

gracias

BLZKZ

creo que hay una funcion para contar ciclos de relog y otra para pasarlo a segundos. En la comparacion le metes esa condición. Lo de los ciclos era no se que de clock xD o clck (busca en ayuda)

Tambien tienes otra solución y es guardar la hora cuando entra en el bucle (no se si en java será getdate o algo asi) y luego comparar en cada iteración con la actual hasta que pasen X sgundos. Asi tambien podras poner la condicion del bucle

Buscalo de todas formas, en c++ es asi http://www.conclase.net/c/librerias/libreria.php?lib=time no creo que se lleve mucho en java

Cyph3r

Hay una función que se llama getmiliseconds en Calendar creas un thread que controle los milisegundos y cuando llegue a lo que quieres haces un break;

BLZKZ

#3 parar un bucle con break siempre lo he visto jodidamente mal. Para que quieres condiciones? si en un for sales con brake es que está mal, y un while o do while con brake? ejem....

Cyph3r

Mhhh crees que esta mal parar con un break ? Segun tu si dentro de un bucle tengo anidados miles de cosas y llega un if () que se si se cumple ya no hace falta continuar todo lo que tengo dentro de ese bucle he de contiuar hasta que haga otra iteracion.

Y en este caso si lo quiere que se pare justo en ese momento que cumpla x ms pues es la unica forma porque si hace mas cosas dentro de ese bucle hasta que vuelva a pasar quizas pasaron x segundos.

Bocasucia

tiene razon cypher xq de la otra forma puede que se quede bloqueado debido a la entrada por teclado y no pare al pasar x segundos

Cyph3r

Hombre no es por eso , ya que en tu condicion podrias añadir por ejemplo:

while(datos entrada && tiempo > 10)

Asi qeu en el momento que la variable que contiene el tiempo fuera mas grande que 10 te saldria pero claro depende que tienes dentro de tu while porque quizas si hay mucha cosa , no salga cuadno cumpla los 10 segundos exactos.

BLZKZ

#7 si es un while no puede tener 3454843435345 cosas porque entonces me juego el cuello que estaria o mal implementado o seria muy muy poco eficiente.

Pero si la eficiencia te da igual... tira con el break que por poder se puede usar.

¿Por cierto #7 alguna vez has estudiado coste de algoritmos? Porque si tienes muchos x=5+6/x*z y cosas asi, el coste es constante y despreciable

salu2

LOc0

Creas un thread para dicho bucle y desde el thread principal esperas al nuevo hilo con:

thread.join(5000); //Le esperas 5 segundos

if(thread.isAlive())
{
 System.out.println("Me cargo el hilo porque tarda mucho");
 thread.stop(); //Te lo cargas
}

El método stop() está "deprecated", es decir, que en futuras versiones de Java es probable que no funcione. En vez de llamar a stop() para cargarte un thread en ejecución puedes usar un FLAG que tu bucle consulte "constantemente" y cuando el thread "principal" lo ponga a FALSE, el thread del bucle termine. El "problema" es si el thread del bucle está bloqueado con datos de entrada/salida hay que hacer más cosas... Más info (inglés) -> http://articles.techrepublic.com.com/5100-10878_11-5144546.html

Salu2 ;)

B

#8

Hay algo mas eficiente para salir de un bucle que un break?

Vamos, si estas seguro seguro de abandonar un bucle, es la mejor opcion. Si se da el caso de chequear la condicion del bucle dentro del mismo bucle, pq tienes que esperar al final?

#9

Una solucion elegante xD aprovechando java. Por cierto, para cpp, has probado a programar con threads? he visto en foros los de posix, pero buscando algo "parecido" a los threads de java?

LOc0

#10

En C++ no sé si habrá alguna librería "estándar" que tenga una clase thread al estilo de Java, aunque tp sería muy difícil hacértela "a mano" si has usado hilos en programación estructurada. En C yo he trasteado con WinAPI32 y POSIX, y en las dos la idea es la misma. Necesitas tener una función para el hilo. Después, desde el main() o la que sea, haces una llamada al sistema para crear el thread pasándole una serie de punteros (la thread-id, la función que correrá el hilo, parámetros para compartir info entre hilo principal y recién creado, etc...) Lo que varía entre el API de Windows y POSIX es esa llamada que tiene distinto nombre y diferentes parámetros. (En Google tienes de esto para aburrir e imagino que tb encontrarás alguna clase Thread que encapsule lo anterior).

Sobre usar "break" en los bucles, a los informáticos (hablo por mi al menos) cuando nos enseñan programación estructurada nos graban a fuego ciertas cosas y una de ellas es que sólo se sale de los bucles cuando la condición de parada definida al principio es TRUE (o la de continuar es FALSE :P ) Esto se nota sobre todo en bucles muy tochos con muchas ramificaciones. Si metes algún break por dentro te estás cargando la estructura y la claridad del código (obligas a LEER TODAS las líneas del bucle para saber exactamente cuándo saldrá) y a nivel más bajo es posible que tb le des algo más de curro al compilador.

El break, si no es dentro de un switch() no es necesario. EL 99.9% de los bucles con breaks se pueden reescribir con if-else, aunque claro está hay que currar un "poquillo" más (no tanto si desde el principio haces las cosas ordenadamente). Y de más eficiencia nada, porque con un simple if te evitas seguir ejecutando el resto del código del bucle si el flag de salida se ha activado en la sentencia anterior.

Salu2 ;)

Soleil

"parar un bucle con break siempre lo he visto jodidamente mal. Para que quieres condiciones? si en un for sales con brake es que está mal, y un while o do while con brake? ejem...."

Un ejemplo de estructura de código donde usar "continue" o "break"
es indispensable o la opción más eficiente:

for(contador...)
{
  if(una condicion)
  {
    comparar algo con algo
    y si es cierto pasar a la siguiente iteración del for() con continue
    (6 o 7 comparaciones)
  }

 switch(posibilidades del if)
  cosas...
}

Sólo quieres usar el switch si ninguna de las comparaciones del if() son ciertas.

Esa estructura de código en un programa real (una máquina virtual de un lenguaje tipo TCL/TK)... (y no se me ocurre forma más eficiente de reescribirlo)

static int 
AllenVM_CPU_LIB_ARITH_PLS
(struct AllenInterp *i, int argc, char **argv, void *pd) 
{
 if(argc < 2) return AllenVM_CPU_Error(i,TLIB_ARITH_EPAR);            
register int p, op=1; register float c=atof(argv[1]); for(p=2; p<argc; ++p) {
if(atof(argv[p])==0) {
if(!strcmp(TLIB_ARITH_PLS,argv[p])) { op = 1; continue; }
if(!strcmp(TLIB_ARITH_MIN,argv[p])) { op = 2; continue; }
if(!strcmp(TLIB_ARITH_MUL,argv[p])) { op = 3; continue; }
if(!strcmp(TLIB_ARITH_DIV,argv[p])) { op = 4; continue; }
if(!strcmp(TLIB_ARITH_MOD,argv[p])) { op = 5; continue; }
if(!strcmp(TLIB_ARITH_POW,argv[p])) { op = 6; continue; } } switch(op) {
case 1: c += atof(argv[p]); break;
case 2: c -= atof(argv[p]); break;
case 3: c *= atof(argv[p]); break;
case 4: c /= atof(argv[p]); break;
case 5: c = c % argv[p]); break;
case 6: c = pow(c,argv[p]); break;
}} char buf[TLIB_ARITH_BSIZE];
snprintf(buf,TLIB_ARITH_BSIZE,"%f",c);
AllenVM_InterpSetResult(i,buf);
return Allen_VM_OK;
};
B

#11

Muchisimas gracias, te voy a seguir preguntando cosas de hilos en cpp xD.

Estoy interesado en pasar algunas herramientas de Java a cpp, antes de que sean taaan grandes que sea un coñazo.

La movida por lo que veo, al no ser librerias standar, necesitaria dos fuentes distintos? uno para windows y otro para linux verdad?

Soleil

#13
Ná, sólo hay que incluír las librerías pertinentes de cada SO para threads.
Si es en win, están en <windows.h>, en linux con <pthread.h> y la opción de gcc -lpthread

Al final se hace lo típico...

#ifdef WIN32
#include <windows.h>
otras cosas de win...
#endif

#ifdef LINUX
#include <pthread.h>
otras cosas de linux...
#endif

O se programa una clase en la que uno meta las librerías anteriores con el mismo interfaz para los dos SO. Seguramente ya habrá alguna por ahí o incluso habrá pthread para win.

BLZKZ

#12 y para eso no es mejor un while? salir con un break de un for es muy desaconsejable, no porque no sea eficiente sino porque está "feo" y es de alguien con pocos recursos ;)

B

#15

Reescribelo como un while si quieres, a ver como queda :P

A mi me parece un codigo bastante claro el segundo ejemplo, y no creo que la eficiencia sea tan abismal, ni de alguien sin recursos ¬¬'. Hay comentarios que mejor guardarselos en mi opinion.

BLZKZ

#16 no me refiero al segundo ejemplo, porque en un puto switch siempre tienes que poner break a no ser que quieras que haga la siguiente opción xD. Vamos es regla de oro de switch, si no pones breaks cuando lo que quieres hacer es un caso unico el programa empezará a hacer cosas extrañas :D

maRc

#13, Qt tiene una clase para hilos muy maja, puede que te interese. Además, te va tanto en Windows como en Linux como en Mac :)

http://doc.trolltech.com/4.4/qthread.html

MTX_Anubis

Todos los for que se tengan que salir en medio del for porque se ha cumplido cierta condición, se pueden escribir como while y son practicamente iguales. De hecho es como debería hacerse.

Luego en el caso de salir de un while con break, ocurre lo mismo. Se puede hacer con if else en vez de meter el break ahí en medio.

Quizás haya casos concretos en el que no sea lo mejor pero a mí no se me ocurren xD

BLZKZ

#19 me comprende ;)

Pues eso, el ejemplo tonto del día, poner un switch dentro de un for y decir que break se usa (ejem ejem)

JuAn4k4

#8 Es coste constante porque lo que calculas es el coste de un algoritmo en funcion de su entrada. Pero el hacer segun que cosas no es para nada inmediato, es constante, pero puede no ser despreciable.

Para salir de un bucle cuando pasen X cosas sin tener que cortar ningun I/O bloqueante, lo mas normal seria.
Poner antes del bucle :
Salir = false.

while ( ( .... ) && ! ( salir ) ) {
....

if ( cond_de_salida ) {salir = true; }
}

Soleil

#20 mi ejemplo no era para mostrar el uso de 'break', sino de 'continue', que a fin de cuentas también cambia el proceso lógico de un bucle for()

BLZKZ

#22 pero no tiene relacion con lo que dije, porque hablaba yo de meter breaks para salir del for, con continue no sales y termina las n iteraciones que le marques

B

Coño, que continue es lo "mismo" que el break. Ambos se pasan la iteracion actual por el forro xD

#18

Muchisimas gracias, eso de que sea independiente de la plataforma es un punto.

Una pregunta, como hago para sincronizar como en Java? utilizando Qthread. Imaginemos que tengo dos hilos y ambos escriben en el puerto serie, evidentemente solo uno a la vez puede. Que palabras, señales, semaforos etc utilizan entre ellos para notificarse?

Te lo pregunto por si ya tienes exeperiencia en ello xD y asi me ahorras curro :P

pd: vale, ya he visto que hay ejemplos etc xD

BLZKZ

#24 porpocopaco es lo mismo, un continue lo que hace es saltar hasta la proxima iteracion, no cargarse todas las iteraciones que quedan saliendose del bucle, por lo tanto hace las n iteraciones un for, que es para lo que esta hecho, para hacer desde el numero dado hasta n pasando por todas y cada una, no cortando a mitad y tragandote las k ultimas iteraciones, es por lo que si tienes un break es mejor usar while+if

para que lo compruebes tu mismo:

#include <iostream>
using namespace std;

int main(){    
for (int i=0; i<10; i++){ cout << i << endl; if (i==4) continue; cout << "hola" << endl; } return 0; }

escribe:
1
hola
2
hola
3
hola
4
5

hola
...

que hace continue?

ahora veamos con break...

#include <iostream>
using namespace std;

int main(){
    for (int i=0; i<10; i++){
        cout << i << endl;
        if (i==4) break;
        cout << "hola" << endl;
        }
    return 0;

}

escribe:

1
hola
2
hola
3
hola
4

y ya está!!!

Sorpresa! continue y break ni por asomo se parecen

MaKi

Lo mejor para trabajar en hilos con c++ es usar librerías multiplataforma como SDL. Las llamadas son tipo SDL_CreateThread y SDL_KillThread y es el mismo código para linux o windows

LOc0

Una alternativa a #12 sin usar 'continue':

spoiler

Salu2 ;)

Soleil

#27 Genial : -)

La alternativa del continue es mucho más rápida en realidad.
El porqué...

if(!strcmp(TLIB_ARITH_PLS,argv[p])) { op = 1; continue; }

Si la primera comparación de strcmp es correcta y a op se asigna 1... me salto las otras
cinco comparaciones con "continue". (comparar cadenas no es particularmente rápido) y
siempre estaré evitando el if para el flag.

Muchas veces ésto no importaría. Cuando hablamos de una parte de una VM que se usa constantemente y que lo que hace es la aritmética más básica de un lenguaje, importa.
Casualmente esa primera operación: TLIB_ARITH_PLS es la suma y es lo que más se usa. : -P

Con GCC 4 para ser exactos, si hago una función recursiva que utilice sumas, restas... etc
en el lenguaje que interpreta esta VM la diferencia acaba siendo exponencial, ya que cada
suma/resta etc... se hace muchas veces.

Para un fibonacci(25) hablamos de varios segundos que se pierden en comparar
operaciones que nunca van a usarse, miles de veces.

Para entender ésto tendría que explicar qué hace exactamente la función
y qué compara con qué.

También es cierto que en otros ámbitos esas comparaciones de más no supondrían apenas nada.
Saludos. (Y gracias por la traducción : -D)

LOc0

#28

Efectivamente. Por eso C con 36 años está donde está y por eso no es el mejor lenguaje para aprender a programar ya que es común confundir libertad con libertinaje :P

Salu2 ;)

SeiYa

A ver, Blazkez dice que si pones un break en un while o en un for es porque no le has implementado correctamente, según la teoría, esa es la impresión que me da a mi :P

Usuarios habituales