Hi,
does any of you have any idea why the self.status variable is not rewritten?
When I run the script below, although it connects to the ip and port mentioned, and receives a message, the self.status is still "down"

the otuput is :
192.168.0.1 down

it should be:
192.168.0.1 'message received'

I am running python 2.5.2 on debian 5.0.4 64bit

#!/usr/bin/env python
from threading import Thread

class testit(Thread):
         def __init__ (self,ip):
                 Thread.__init__(self)
                 self.ip = ip
                 self.status = "down"

          def run(self):
                 PORT = 1000
                 s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
                 s.settimeout(3)
                 s.connect((self.ip, PORT))
                 s.send('u\n')
                 data = s.recv(1024)
                 s.close()
                 self.status = repr(data)


current=testit("192.168.0.1")
current.start()
print current.ip,current.status

The problem is that the print statement is executed before the testit thread had time to establish a connection and receive data. The only thing to do is to wait before the print statement. There are 2 ways to wait here:
First way: you wait until the testit thread is terminated before you make the print statement, for this, you must use the join method like this

current=testit("192.168.0.1")
current.start()
current.join()
print current.ip,current.status

This is probably not what you want to do, so the Second way to wait is to use a threading.Condition instance. You can do it this way

# from __future__ import with_statement # uncomment if python 2.5
from threading import Condition, Thread
from contextlib import contextmanager

@contextmanager
def acquired(condition):
    condition.acquire()
    try:
        yield condition
    finally:
        condition.release()

connection_done = Condition()

class testit(Thread):
    ....
    def run(self):
        try:
            port = 1000
            ...
            self.status = repr(data)
        finally:
            with acquired(connection_done):
                connection_done.notify()
        ...

current=testit("192.168.0.1")
with acquired(connection_done):
    current.start()
    connection_done.wait()
    if current.status == "down":
        print "testit thread could not establish a connection"
print current.ip,current.status

Edited 6 Years Ago by Gribouillis: n/a

Comments
nice response.Thanks

After line
data = s.recv(1024)
put in a test print
print data

What do you get?

i get the data correctly
the join method works but it slows down the script a lot

The problem is that the print statement is executed before the testit thread had time to establish a connection and receive data. The only thing to do is to wait before the print statement. There are 2 ways to wait here:
First way: you wait until the testit thread is terminated before you make the print statement, for this, you must use the join method like this

current=testit("192.168.0.1")
current.start()
current.join()
print current.ip,current.status

This is probably not what you want to do, so the Second way to wait is to use a threading.Condition instance. You can do it this way

# from __future__ import with_statement # uncomment if python 2.5
from threading import Condition, Thread
from contextlib import contextmanager

@contextmanager
def acquired(condition):
    condition.acquire()
    try:
        yield condition
    finally:
        condition.release()

connection_done = Condition()

class testit(Thread):
    ....
    def run(self):
        try:
            port = 1000
            ...
            self.status = repr(data)
        finally:
            with acquired(connection_done):
                connection_done.notify()
        ...

current=testit("192.168.0.1")
with acquired(connection_done):
    current.start()
    connection_done.wait()
    if current.status == "down":
        print "testit thread could not establish a connection"
print current.ip,current.status

it seems the join method makes the script unthreaded.I added a start time for the object and it seems it scans about 1 / second.

it seems the join method makes the script unthreaded.I added a start time for the object and it seems it scans about 1 / second.

my bad, works well.

This question has already been answered. Start a new discussion instead.