|
Mostrar Mensajes
|
Páginas: 1 [2] 3
|
11
|
Programación / Java / Re: Codigo en Java que no hace lo que deberia
|
en: 23 Enero 2014, 18:22 pm
|
Fixed public class Hilo extends Thread { private int tipoHilo; private int nVueltas; public Hilo(int nVueltas, int tipoHilo) { this.nVueltas = nVueltas; this.tipoHilo = tipoHilo; } public void run() { synchronized (n) { switch (tipoHilo) { case 0: for (int i = 0; i < nVueltas; i++) n = n + 1; ; break; case 1: for (int i = 0; i < nVueltas; i++) n = n - 1; ; break; } } } Hilo p = new Hilo(10000, 0); Hilo q = new Hilo(10000, 1); p.start(); q.start(); p.join(); q.join(); } }
La razón porque al principio no funcionaba es porque habías puesto el keyword synchronized dentro del un loop. Cuando se iniciaba un ciclo en el loop, uno de los 2 thread tomaba el lock y el otro esperaba a que liberen el lock. El problema esta en que el lock se libera cuando termina cada ciclo (son 10,000 ciclos como haz indicado), y puede pasar 2 cosas: - El thread que habia tomado el lock toma el lock de nuevo
- El thread que estaba esperando que liberen el lock toma el lock.
Por lo tanto, en un momento la variable se puede incrementar y en el siguiente puede que disminuya, y en el siguiente puede incrementarse o disminuirse, y asi. Ahora al poner el keyword al inicio de todo el metodo, el lock se libera solo cuando el metodo se termine de ejecutar, y cuando se termina de ejecutar, entonce el segundo thread puede tomar el lock ya que se ha liberado. Saludos. Que? no es como dices, porque tal como tu comentas se ejecutaria todo de manera secuencial, mientras que lo que interesa es el paralelismo lo maximo posible para incrementar el rendimiento. Poner el synchronized dentro del bucle no tiene problema, ya que la sección critica es el contador (la variable n). El problema del codigo que puse, es que si utilizas un objeto como cerrojo y lo usas, este se modifica y sus propiedades como cerrojo se pierden y se produce el dichoso entrelazado. Como dije en el primer comentario, si en vez de poner el cerrojo el objeto n de la clase integer ponemos cualquier otro objeto y este no se modifica en ningun momento, el codigo funcionara perfectamente y no existira entrelazado. Por cierto, lo de poner el synchronized en el switch es una burrada enorme ... porque la gracia de este codigo es ejecutarlo de forma concurrente mientras que tu manera le quita toda la concurrencia posible...
|
|
|
12
|
Programación / Java / Re: Codigo en Java que no hace lo que deberia
|
en: 19 Enero 2014, 10:57 am
|
public class Hilo extends Thread { private int tipoHilo; private int nVueltas;
MMM puede ser porque la variable n es privada de la clase hilo???? No se mucho de java pero supongo que esa variable tendría que ser publica y en el main el print seria asi System.out.println(Hilo.n);Para nada... la encapsulacion de datos es hacerlas privadas aun asi no interfiere en el resultado que sea publica.
|
|
|
13
|
Programación / Java / Codigo en Java que no hace lo que deberia
|
en: 18 Enero 2014, 21:09 pm
|
Buenas, a ver si me podeis explicar que ocurre con este codigo: Resulta que deberia de darme un resultado final de cero, pero en vez de eso me da un resultado indeterminado, os pongo aqui el codigo: public class Hilo extends Thread { private int tipoHilo; private static Integer n = new Integer(0); private int nVueltas; public Hilo(int nVueltas, int tipoHilo) {this.nVueltas=nVueltas; this.tipoHilo=tipoHilo;} public void run() { switch(tipoHilo){ case 0: for(int i=0; i<nVueltas; i++) synchronized(n){ n=n+1;}; break; case 1: for(int i=0; i<nVueltas; i++){ synchronized(n){n=n-1;}; break; } } public static void main(String[] args) throws Exception { Hilo p = new Hilo(10000, 0); Hilo q = new Hilo(10000, 1); p.start(); q.start(); p.join(); q.join(); System.out.println(n); } } El codigo no esta mal, ya que si cambio el cerrojo de synchronized por otro que no sea de tipo Integer, funciona perfectamente, lo que deja entrever que no se puede usar un cerrojo que se vaya a modificar posteriormente (hago un n++ con la n declarada como integer). Algun tipo de explicacion de por que no puedo usar este cerrojo? Me he llevado una inmensa sorpresa y dolores de cabeza por culpa de este error!! Un saludo y gracias!
|
|
|
14
|
Programación / Java / Duda con pool de threads en java
|
en: 11 Enero 2014, 20:50 pm
|
Buenas, tengo una duda con los pool de threads, tengo la siguiente imagen: Es de un examen que me estoy preparando y resulta, que no tengo ni idea de a que pool de threads puede pertenecer. Puede ser a un newCachedThreadPool o un ThreadPoolExecutor, creo que tiene mas opciones de ser la segunda, ya que cuando se van creando mas hilos no se resiente el tiempo, cosa que puede corregir el ThreadPoolExecutor... Que pensais vosotros??
|
|
|
15
|
Programación / ASM / Re: Como imprimir los valores de un vector de enteros?
|
en: 7 Enero 2014, 10:36 am
|
Buenas, termine el programa que trataba de hacer, lo voy a poner aqui por si alguna persona le quiere echar un vistazo o a modo docente por si alguien quiere aprender, tengo mas o menos comentado para que sirve cada linea. El programa es muy basico y lo que hace es ordenar un vector en orden creciente mediante el algoritmo de la burbuja. Lo ideal seria utilizar funciones en el codigo, pero no se hacerlas aun correctamente, ya que siempre me petan en el ret, se ve que no se guardar bien la direccion a la que debe volver... ;Ordenar un vector dado mediante el algoritmo de la burbuja
.Const
.Data
Vec1 DD 8, 10, 2, 4, 5, 6, 1, 2, 3, 4, 7, 8, 9, 5, 6, 2, 3, 1, 4, 7 ;Aqui esta el vector Num DD 20 ;Numero de elementos
.Code
start: Invoke printf, "Vamos a Ordenar el vector Vec1 ya iniciado mediante el algoritmo de la burbuja: " Invoke puts, "", "\N" ;Salto de Linea Invoke printf, "Vector a Ordenar: " Invoke puts, "", "\N" ;Salto de Linea
;Imprimir por pantalla el vector:
imprimir: Mov Ebx, 0 ;Ponemos el contador del bucle a cero. Mov Esi, Addr Vec1 ;Se le pasa la direccion base para movernos por todo el vector bucle: Cmp Ebx, [Num] ;Comparacion de Eax y N Je > fin ;Salta si Eax y N son iguales, por lo que seria igual a if(Eax < N) Invoke printf, "%d, ", [Esi] ;Imprime el valor que hay en la direccion de memoria Inc Ebx ;Eax++ Add Esi, 4 ;Se le suma 4 para movernos sobre el vector elemento a elemento Jmp < bucle ;Salto incondicional, se usa < porque el salto es hacia atras. fin: Invoke puts, "", "\N" ;Salto de Linea
;Fin parte imprimir Vector por pantalla
;Ordenar los elementos del vector con algoritmo burbuja burbuja: Mov Esi, 0 ;Contador i del bucle fuera Mov Edi, 0 ;Contador j del bucle dentro Mov Ebx, Addr Vec1 ;Metemos en Ebx la direccion base de vec1 para el bucle de fuera while_fuera: Cmp Esi, [Num] Je > fin_whilefuera ;while(i < Num) Mov Edi, Esi ;Hacemos j = i al iniciar el bucle Mov Ebp, Ebx ;Metemos en Ebp la direccion base por donde vamos a empezar que sera en vec1[i]
while_dentro: Cmp Edi, [Num] Je > fin_whiledentro ;while(j < Num) Mov Eax, [Ebx] ;No se pueden comparar [Ebx] y [Ebp] por lo que los hemos pasado a Eax y Ecx Mov Ecx, [Ebp] if: Cmp Eax, Ecx Jbe > fin_if ;if (Vec1[i] > Vec1[j]) ;Invoke printf, "Valor de Vec1[%d]= %d <-- Vec1[%d]= %d, ", Esi, [Ebx], Edi, [Ebp] ;Invoke puts, "", "\N" ;Salto de Linea Mov Eax, [Ebx] ;aux1 = vec1[i] Mov Edx, [Ebp] ;aux2 = vec1[j] Mov [Ebx], Edx ;vec1[i] = aux2 Mov [Ebp], Eax ;vec1[j] = aux1 fin_if: Inc Edi ;j++ Add Ebp, 4 Jmp while_dentro ;volvemos al bucle while dentro fin_whiledentro: Inc Esi ;i++ al terminar el while_dentro Add Ebx, 4 Jmp while_fuera ;volveos al bucle while fuera fin_whilefuera:
;Imprimimos de nuevo los resultados Invoke printf, "Vector Ordenado: " Invoke puts, "", "\N" ;Salto de Linea
imprimir2: Mov Ebx, 0 ;Ponemos el contador del bucle a cero. Mov Esi, Addr Vec1 ;Se le pasa la direccion base para movernos por todo el vector bucle2: Cmp Ebx, [Num] ;Comparacion de Eax y N Je > fin2 ;Salta si Eax y N son iguales, por lo que seria igual a if(Eax < N) Invoke printf, "%d, ", [Esi] ;Imprime el valor que hay en la direccion de memoria Inc Ebx ;Eax++ Add Esi, 4 ;Se le suma 4 para movernos sobre el vector elemento a elemento Jmp < bucle2 ;Salto incondicional, se usa < porque el salto es hacia atras. fin2: Invoke puts, "", "\N" ;Salto de Linea
;Fin parte Ordenar los elementos Exit: Invoke system, "pause" Xor EAX, EAX Invoke ExitProcess, EAX
;Fin del programa principal
|
|
|
16
|
Programación / ASM / Re: Como imprimir los valores de un vector de enteros?
|
en: 4 Enero 2014, 15:33 pm
|
Hola, ten cuidado al usar ECX que la funcion printf por ahi no preserva ecx. Recuerda que los contadores seguros son esi, edi y ebx. Te doy una pista si quieres imprimir numeros menores a 10. 8 no es lo mismo que "8" El primero es un entero. El segundo es un caracter ascii. El valor del caracter ascii "8" es 56. De "0" 48, "1" es 49... http://www.asciitable.com/Luego otro problema. Vect1 DW.... mov ecx, addr vect1 printf..... [ecx] printf como parametro te pide un Double Word. DW creo que significa Data Word. Necesitas un DD, Data Double Word. De lo contrario en vez te tomar 8.... te va tomar 98 (primer y segundo elemento del vector invirtiendolos) Saludos Gracias por contestar, el tema de los caracteres ASCII no tengo problemas, al menos en C. Ya he conseguido acceder a la primera posicion, el error era usar el registro Ecx tal como comentaste! He usado Esi y puesto DD en vez de DW (este fue el tipico cambio desesperado...) y a la primera me ha salido el 8. ¿Podrias explicarme un poco mas eso del registro Esi y Ecx? Comprendo que Ecx es un registro que tiene un proposito especifico, pero ¿sabes cual es el problema con printf que se modifica? Elegi el registro Ecx por ya tenia usados Eax y Ebx, vamos por orden, vaya ojo el mio que me fui a fijar en el que se modifica con printf... Ya no se me olvida en la vida!!!
|
|
|
17
|
Programación / ASM / Como imprimir los valores de un vector de enteros?
|
en: 3 Enero 2014, 20:35 pm
|
Buenas a todos, resulta que como se podran pensar soy muy novato con esto de ensamblador x86 y aqui viene mi duda: Estoy tratando de imprimir los valores que contiene un vector, les pongo aqui el codigo que tengo por el momento: .Const
.Data
Vec1 DW 8, 9, 2, 4, 5, 6, 1, 2, 3, 4, 7, 8, 9, 5, 6, 2, 3, 1, 4, 7 ;Aqui esta el vector
.Code
start: Mov Ecx, Addr Vec1 ;Se le pasa la direccion base para movernos por todo el vector Mov Eax, 0 ;Contador del vector, se pone el contador a 0
Invoke printf, "El valor de la posicion %d es: %d", Eax,[Ecx] ;[b]Aqui es donde viene la gracia, quiero ver el valor de la posicion 0 del vector y me sale un numero diferente!![/b] Invoke puts, "", "\N" ;Salto de Linea Exit: Invoke system, "pause" Xor Eax, Eax Invoke ExitProcess, Eax ;Fin del programa principal Bueno pues como pongo en el codigo, lo que me ocurre es que en vez de aparecerme la primera posicion del vector lo que me aparece es un numero que no tiene nada que ver y que tampoco es la direccion de memoria del vector. Creo que la teoria me la conozco y es lo que trato de aplicar, le paso a un registro la direccion donde se encuentra la direccion base del vector, y a partir de ahi voy recorriendo este aumentando la direccion en funcion de lo que ocupen los enteros, en este caso son dw por lo que se incrementara de 2 en 2 bytes, pero en la primera posicion el incremento es cero por lo que con mi codigo tendria que verse... He probado sumandole 2 o mas... quitandole los corchetes a Ecx y mil perradas, pero no lo cosigo . Se que con este codigo no se puede recorrer todo el vector, he puesto aqui solo parte para que se vea la primea posicion para simplificarlo, mi problema solo es ese, con el bucle no tengo problemas (aun... xD) A ver si me pueden decir donde esta mal el codigo!! Un saludo!!
|
|
|
18
|
Programación / Programación C/C++ / Re: Calculadora en C (Turbo C 2.0)
|
en: 29 Diciembre 2013, 10:35 am
|
Dios, hace años que no veo un GOTO, eso en C esta mas que prohibido, no se si vienes de ensamblador o que estas siguiendo un tutorial de hace mas de 20 años, pero no se cuantos años hace que se desaconsejo el empleo de goto ya que induce a un codigo ilegible y dificilmente modificable, lo que comunmente se llama codigo espaguetti. Un link de wikipedia donde explica mejor la constroversia con goto: http://es.wikipedia.org/wiki/GOTOUn saludo!
|
|
|
19
|
Programación / Programación C/C++ / Re: Problemas con ficheros en C
|
en: 27 Diciembre 2013, 20:56 pm
|
Entonces ok, dejo el tema en paz, solo una duda, si la biblioteca fstream es parte del la biblioteca stantart de c++ no se podra agregar en un fichero .c cierto? Y esta claro que esta trabajando con C puesto que las otras bibliotecas conservan el .h Un saludo.
|
|
|
|
|
|
|