[Python-es] raro problema con hilos

39 views
Skip to first unread message

xiao xiong mao panda rojo

unread,
Aug 27, 2012, 5:47:47 PM8/27/12
to python es lista
estoy haciendo algunos experimento con hilos
pero algo anda mal
la idea era hacer una ventana y que esta se haga visible al darle una orden por un socket
cuando reciba una cierta cadena x el socket la ventana debe realizar la orden

lo raro es k no la realiza, sino hasta después de k se ejecuten varios eventos en la ventana

este es el código que uso para enviar la orden


import socket
import time
import sys
#str = sys.argv[1]
str = "hola"
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("localhost", 1333))
#time.sleep(3)
s.send(str)
s.close()
print "e


completa su ejecución sin errores y de inmediato

este es el el hilo principal

import pygtk
pygtk.require('2.0')
#import gtk
#import os#, sys
import socket
import ventana
import thread
import time
import sys


try:
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(("",1333))
    server.listen(1)
except:
    print "puerto 1333 ocupado\n?Otra instancia de la aplicacion se esta ejecutando?"
    exit()

def escuchapuerto(e,i):
    global server
    time.sleep(15)
    while True:       
        #try:
        socket_cliente, datos_cliente = server.accept()
        mensaje = socket_cliente.recv(32)
        print mensaje
        if mensaje == "hola":
            #ventana.ventana.window.set_visible(True)
            #ventana.ventana.window.maximize()
            ventana.ventana.entry.set_text(mensaje)
            #time.sleep(3)               
        #except:
        #    print "error escuchando puerto"
   
thread.start_new_thread(escuchapuerto,(0,0))# no se ejecuta normalmente
ventana.start()

en este caso debe escribir un texto en un gtk.entry
ejecuto el primer script, envia la cadena sin errores
pero la ventan principal no hace nada
la doy click a los botones y otros eventos, despues de ejecutarse entre 3 y 10 eventos recién aparece el texto

hice casi lo mismo en java y funciona perfecto, la ventana principal responde sin  problemas

que le esta pasando??

Chema Cortes

unread,
Aug 27, 2012, 6:49:15 PM8/27/12
to La lista de python en castellano
El día 27 de agosto de 2012 23:47, xiao xiong mao panda rojo
<ailurus...@hotmail.com> escribió:
¿No serán muchos 15 segundos?

> while True:
> #try:
> socket_cliente, datos_cliente = server.accept()
> mensaje = socket_cliente.recv(32)
> print mensaje
> if mensaje == "hola":
> #ventana.ventana.window.set_visible(True)
> #ventana.ventana.window.maximize()
> ventana.ventana.entry.set_text(mensaje)
> #time.sleep(3)
> #except:
> # print "error escuchando puerto"
>
> thread.start_new_thread(escuchapuerto,(0,0))# no se ejecuta normalmente
> ventana.start()
>
> en este caso debe escribir un texto en un gtk.entry
> ejecuto el primer script, envia la cadena sin errores
> pero la ventan principal no hace nada
> la doy click a los botones y otros eventos, despues de ejecutarse entre 3 y
> 10 eventos recién aparece el texto
>
> hice casi lo mismo en java y funciona perfecto, la ventana principal
> responde sin problemas
>
> que le esta pasando??




--
Hyperreals *R: http://ch3m4.org/blog
Quarks, bits y otras criaturas infinitesimales
_______________________________________________
Python-es mailing list
Pyth...@python.org
http://mail.python.org/mailman/listinfo/python-es
FAQ: http://python-es-faq.wikidot.com/

xiao xiong mao panda rojo

unread,
Aug 27, 2012, 6:56:33 PM8/27/12
to p...@ch3m4.org, python es lista
eso es solo el tiempo antes de que comience a escuchar
igual sin esa linea me da el mismo resultado
no importa el tiempo k espera
solo aparece el texto después de ejecutar algunos otros eventos

> Date: Tue, 28 Aug 2012 00:49:15 +0200
> From: pyc...@gmail.com
> To: pyth...@python.org
> Subject: Re: [Python-es] raro problema con hilos

Chema Cortes

unread,
Aug 28, 2012, 4:00:21 AM8/28/12
to La lista de python en castellano
El día 28 de agosto de 2012 00:56, xiao xiong mao panda rojo
<ailurus...@hotmail.com> escribió:

> eso es solo el tiempo antes de que comience a escuchar
> igual sin esa linea me da el mismo resultado
> no importa el tiempo k espera
> solo aparece el texto después de ejecutar algunos otros eventos

Vale. Entonces intenta determinar mejor dónde falla:

- ¿El servidor recibe los datos o es un problema de actualización de la ventana?

- ¿Afecta el tamaño del buffer en la recepción? ¿Qué pasa si no hay
buffer? ¿Qué pasa si el mensaje tiene mayor longitud que el buffer?

- ¿Afecta en algo si cambias el timeout (socket.timeout(value))?

- ¿Qué pasa si fuerzas al cierre inmediato del socket con shutdown
antes de hacer close?


Prueba primero con la última pregunta. Según la documentación, un
.close() no significa que se cierre inmediatamente el socket. Tal como
lo has programado, el servidor no sabe cuándo ha terminado el cliente
de enviar el mensaje hasta que se cierra el socket por timeout.

xiao xiong mao panda rojo

unread,
Aug 28, 2012, 6:15:50 PM8/28/12
to p...@ch3m4.org, python es lista
hola ch3m4
hice algunas pruebas
agrege el "shutdown" en mi cliente antes de "close"
no hay diferencia

me di cuenta k "socket_cliente.recv(4) "
el "4" es el numero de bytes, pensé k era de bits
cambie el largo de la cadena
la longitud no importa, mayor o menor; mismo problema

cambiar el timeout me dio una pista
ni mi server (server = socket.socket(socket.AF_INET, socket.SOCK_STREAM))
o mi socket_cliente (socket_cliente, datos_cliente = server.accept())
ni mi programa de envio (s = socket.socket(socket.AF_INET, socket.SOCK_STREAM))
ninguno tiene un atributo llamado .timeout()
me imprime un error con cada uno
solo si llamo socket.timeout() funciona. pero asi no le estoy dando el dato a los objetos con lo que estoy trabajando

pero paso algo interesante. incluso la impresion de errores necesita k ocurra algún evento.
y si hago "print mensaje,"mensaje recibido" "
primero imprime la variable mensaje y unos eventos después la cadena "mensaje recibido" y mas eventos después se actualiza la ventana

parece k el problema es k el hilo no se ejecuta libremente. se queda esperando una oportunidad de ejecutarse o algo así
es muy raro
luego investigare mas sobre hilos y otras formas de iniciar un nuevo hilo

gracias por responder


> Date: Tue, 28 Aug 2012 10:00:21 +0200

> From: pyc...@gmail.com
> To: pyth...@python.org
> Subject: Re: [Python-es] raro problema con hilos
>

Chema Cortes

unread,
Aug 28, 2012, 8:04:08 PM8/28/12
to La lista de python en castellano
El día 29 de agosto de 2012 00:15, xiao xiong mao panda rojo
<ailurus...@hotmail.com> escribió:

> hice algunas pruebas
> agrege el "shutdown" en mi cliente antes de "close"
> no hay diferencia
>
> me di cuenta k "socket_cliente.recv(4) "
> el "4" es el numero de bytes, pensé k era de bits
> cambie el largo de la cadena
> la longitud no importa, mayor o menor; mismo problema
>
> cambiar el timeout me dio una pista
> ni mi server (server = socket.socket(socket.AF_INET, socket.SOCK_STREAM))
> o mi socket_cliente (socket_cliente, datos_cliente = server.accept())
> ni mi programa de envio (s = socket.socket(socket.AF_INET,
> socket.SOCK_STREAM))
> ninguno tiene un atributo llamado .timeout()
> me imprime un error con cada uno
> solo si llamo socket.timeout() funciona. pero asi no le estoy dando el dato
> a los objetos con lo que estoy trabajando

El timeout es un modo común a todo el módulo socket. El cambiarlo era
por descartar cosas.

> pero paso algo interesante. incluso la impresion de errores necesita k
> ocurra algún evento.
> y si hago "print mensaje,"mensaje recibido" "
> primero imprime la variable mensaje y unos eventos después la cadena
> "mensaje recibido" y mas eventos después se actualiza la ventana
>
> parece k el problema es k el hilo no se ejecuta libremente. se queda
> esperando una oportunidad de ejecutarse o algo así
> es muy raro
> luego investigare mas sobre hilos y otras formas de iniciar un nuevo hilo

También a mí me ha dado alguna pista.

Con pygtk existe un doble bloqueo: el GIL (Global Interpreter Lock) de
python y el bloqueo propio de gdk. Cuando se ejecuta gtk.main() se
desbloquea gdk para que sea usado por otro hilo; pero no libera el GIL
en ése momento, con lo que queda bloqueado el intérprete python hasta
que no se produzca algún evento en el hilo principal. Todos los hilos
se paran, sólo la librería gtk está en funcionamiento.

La solución es pedir que los desbloqueos de gdk y GIL vaya parejos
invocando gtk.gdk.threads_init() antes de gtk.main():

http://www.pygtk.org/docs/pygtk/gdk-functions.html#function-gdk--threads-init

xiao xiong mao panda rojo

unread,
Aug 29, 2012, 12:09:46 AM8/29/12
to p...@ch3m4.org, python es lista
eres grande ch3m4
funciona perfecto
seguro te tomo mucho tiempo encontrar el problema
muchas gracias
como agradecimiento te contare de k se trata todo esto

hice una aplicación para leer diccionarios offline (de la k estoy orgulloso XD)
queria k la ventana venga al frente con una combinación de teclas. pero java no detecta las teclas sin la ventana
la opción era hacer una librería en C
:/
así k lo mas cercano fue configurar mi gnome para ejecutar " java -jar /home/panda/dic.jar"
al ejecutarse el una nueva instancia de fija si el puerto esta libre. si esta ocupado envia una cadena
la instancia k ya se esta ejecutando escucha en un hilo y cuando recibe la cadena correcta pone la ventana en frente con "setVisible(True)"
sufrí bastante para hacerlo funcionar los sockets en java. pero fue divertido
ahora haré lo mismo en la version k estoy "traduciendo" a python


dejare la versión de java, tal ves a alguien le sirva y cuando la versión de python funcione bien la pondré tambien




import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import javax.swing.JFrame;

public class Main {
static ServerSocket SERVER_SOCKET;
static Socket socket;
static DataInputStream dataInput;
static DataOutputStream dataOutput;
   
    public static void main(String[] args) {       
      try {
        SERVER_SOCKET = new ServerSocket(1334);//si ya se esta ejecutando el puerto estara ocupado
    } catch (IOException x) {
        System.out.println("puerto 1334 ocupado\n¿Otra instancia de la aplicación se está ejecutando?");
        try{
            System.out.println("enviando señal");//como ya se esta ejecutando solo hay k ponerlo al frente
            socket = new Socket("localhost", 1334);//conectarse al puerto
            dataOutput = new DataOutputStream(socket.getOutputStream());//esta tonteria es necesaria en java¬¬
            dataOutput.writeUTF("kdjhfiufbd.Show!!!");//enviando orden para k le ventana se haga visible
            socket.close();
        }
        catch(Exception e){e.printStackTrace();}
            System.exit(0);//ya enviada la orden se detiene
    }

        ventana obj = new ventana();//llamar a la ventana principal
        //obj.setVisible(true);
        try{
            if(args[0].equals("hide")){obj.setVisible(false);}else{obj.setVisible(true);}}// si revice un argumento "hide" la ventano no sera visible. cualquier otro argummento sera ignorado
        catch(Exception e){obj.setVisible(true);}//sin arguemntos, visible

        while (true){//la vetana principal ya esta funcionando y ahora escuchara cuando se le ordene ir al frente
            try{
        Socket cliente = SERVER_SOCKET.accept();//espera k algo se coneccte
        dataInput = new DataInputStream(cliente.getInputStream());
        String text = dataInput.readUTF();//espera a recibir una orden
        //System.out.println(text);
        if (text.equals("kdjhfiufbd.Show!!!")){obj.setVisible(true);}//se asegura k la orden sea de la misma aplicacion y pone la ventana al frente
              }
            catch(Exception e){e.printStackTrace();}
        }

    }

}




> Date: Wed, 29 Aug 2012 02:04:08 +0200

> From: pyc...@gmail.com
> To: pyth...@python.org
> Subject: Re: [Python-es] raro problema con hilos
>
Reply all
Reply to author
Forward
0 new messages