Thread error

  • Thread starter Salvatore Di Fazio
  • Start date
S

Salvatore Di Fazio

Hi guys,
when I close the application I get the following error:

-----------------------------
Traceback (most recent call last):
File "main.py", line 88, in <module>
while exit : pass
KeyboardInterrupt
Unhandled exception in thread started by
Error in sys.excepthook:

Original exception was:
-----------------------------

This is the code:
-----------------------------
# Echo client program
import socket
import sys
import thread
import mtalk

HOST = '192.168.0.115' # The remote host
PORT = 3580 # The same port as used by the server

buff = ""
buffStatus = 0
s = None
exit = 1

############### keywordDataIn ###############
def keywordDataIn():
global buff, buffStatus, exit
talkmsg = mtalk.TalkMessage()
while exit:
line = sys.stdin.readline()
if line == 'quit\n':
exit = 0
break
elif line != '\n':
lock.acquire()
buff = talkmsg.Make(line)
buffStatus = 1
lock.release()
elif line == '\n':
pass

############### dataToServer ###############
def dataToServer():
global buff, buffStatus, exit
while exit:
if buffStatus == 1:
try:
lock.acquire()
s.sendall(buff)
buff = ""
buffStatus = 0
lock.release()
except: socket.error
pass # errore da controllare

############## dataFromServer ##############
def dataFromServer():
global exit
while exit:
data = s.recv(1024)
print 'Received', repr(data)




############### Main ###############
if __name__ == "__main__" :

for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC,
socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res

buffStatus = 0

try:
s = socket.socket(af, socktype, proto)
except socket.error, msg:
print("Unexpected error")
s = None
sys.exit(1)

try:
s.connect(sa)
print 'Connection ...'
except socket.error, msg:
print("The server was not reachable")
s.close()
s = None
sys.exit(1)

print 'Connected'

# mutex
lock = thread.allocate_lock()
thread.start_new_thread(keywordDataIn, ())
thread.start_new_thread(dataToServer, ())
thread.start_new_thread(dataFromServer, ())

while exit : pass

s.close()
 
D

Dennis Lee Bieber

# Echo client program
import socket
import sys
import thread

Personally, I'd use the threading module instead of thread
buff = ""
buffStatus = 0
s = None
exit = 1
For a few versions now, Python has support boolean constants of True
and False... and

exit = True

is quite misleading, when it means DO NOT EXIT
############### keywordDataIn ###############
def keywordDataIn():
global buff, buffStatus, exit
talkmsg = mtalk.TalkMessage()
while exit:
line = sys.stdin.readline()
if line == 'quit\n':
exit = 0
break

The break is not needed... you just set exit to Fals, so the next
cycle of the while loop will end.
elif line != '\n':
lock.acquire()

You've declared buff, buffStatus, and exit as global, I'm surprised
you didn't include lock
buff = talkmsg.Make(line)
buffStatus = 1
lock.release()
elif line == '\n':
pass

############### dataToServer ###############
def dataToServer():
global buff, buffStatus, exit
while exit:
if buffStatus == 1:
try:
lock.acquire()
s.sendall(buff)
buff = ""
buffStatus = 0
lock.release()
except: socket.error
pass # errore da controllare
For all practical purposes, these two threads are serialized... If
buffStatus is 1 and this thread gets the lock, the other thread can not
do anything... And this thread can not do anything until the other sets
the status for it... you could just as easily have one thread do:

while ...:
fill_buffer()
send_buffer()
############## dataFromServer ##############
def dataFromServer():
global exit
while exit:
data = s.recv(1024)
print 'Received', repr(data)




############### Main ###############
if __name__ == "__main__" :

for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC,
socket.SOCK_STREAM):
af, socktype, proto, canonname, sa = res

buffStatus = 0

try:
s = socket.socket(af, socktype, proto)
except socket.error, msg:
print("Unexpected error")
s = None
sys.exit(1)

try:
s.connect(sa)
print 'Connection ...'
except socket.error, msg:
print("The server was not reachable")
s.close()
s = None
sys.exit(1)

print 'Connected'

# mutex
lock = thread.allocate_lock()
thread.start_new_thread(keywordDataIn, ())
thread.start_new_thread(dataToServer, ())
thread.start_new_thread(dataFromServer, ())

while exit : pass
Note that, nowhere do you wait for the threads to STOP... They may
not get CPU time between exit going False and the main program ending.
Also, a busy wait loop like this is quite wasteful of CPU... Better to
do something like:

while exit:
time.sleep(0.1)

allows the threads to switch... I forget what the setting is, but I
thought the Python runtime doesn't do a preemptive swap until something
like 100 bytecodes have been executed. "while exit: pass" may only be 10
or so bytecodes, meaning the loop will run 10 times BEFORE another
thread can do anything.
s.close()
-----------------------------

I don't have mtalk or stuff, so this is untested:

watch out for line wrapping in the news client
-=-=-=-=-=-=-
# Echo client program
import socket
import sys
import threading #
import Queue #
import mtalk

HOST = '192.168.0.115' # The remote host
PORT = 3580 # The same port as used by the server

Done = False #Note how tense of "false" matches the meaning of
"Done"
xferQueue = Queue.Queue() #inter-thread data transfer; no shared
buffer or locks

def keywordDataIn():
global Done
talkMsg = mtalk.TalkMessage()
while not Done:
line = sys.stdin.readline()
if line == "quit\n":
Done = True
elif line != "\n":
buff = talkMsg.Make(line)
xferQueue.put(buff) #send the line to the socket send
#no time.sleep() needed as sys.stdin.readline blocks
#fortunately you don't have to loop to test Done until it
returns

############### dataToServer ###############
def dataToServer():
while not Done:
try:
buff = xferQueue.get(timeout=1.0) #get a data line to send
s.sendall(buff)
except socket.error, msg: #I'm not sure what your intent was
#you had socket.error on the right-side of the :
print "Error sending over socket:\n\t%s\n\t%s" % (msg,
repr(buff))
except socket.timeout, msg:
print "Timeout in sending over socket:\n\t%s" % msg
except Queue.Empty:
pass #timeout on queue get is to allow for loop to test
Done
#but is slow enough not to hit much CPU... does mean
up to
#one second from when Done is set True before dTS
exits


############## dataFromServer ##############
def dataFromServer():
while not Done:
try:
data = s.recv(1024)
print "Received: ", repr(data)
except socket.timeout, msg:
pass #timeout is used to allow loop to test Done
except socket.error, msg:
print "Error reading socket:\n\t%s" % msg



############### Main ###############
if __name__ == "__main__" :

res = socket.getaddrinfo(HOST,
PORT,
socket.AF_UNSPEC,
socket.SOCK_STREAM)
(af, socktype, proto, canonname, sa) = res[-1] #only the last was
used


try:
s = socket.socket(af, socktype, proto)
s.settimeout(1.0) #
except socket.error, msg:
print "Unexpected error creating socket:\n\t%s" % msg
sys.exit(1)

try:
print "Connecting..."
s.connect(sa)
#no print here as it would only be executed when the connection
took place
except socket.error, msg:
print "Error connecting to server:\n\t%s" % msg
s.close()
sys.exit(1)

print "Connected"

kdi = threading.Thread(target=keywordDataIn)
dts = threading.Thread(target=dataToServer)
dfs = threading.Thread(target=dataFromServer)

kdi.join() #wait for kdi thread to exit NO CPU HOG BUSY LOOPS
dts.join() #...
dfs.join() #...

s.close()
-=-=-=-=-=-=-=-

Having gotten this far... I suspect part of your exception is
because: 1) you are exiting before the threads have time to finish, 2)
the dFS thread won't finish until the last .recv() finishes; that is a
blocking request which I use a timeout setting on to allow for checking
of Done
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
S

Salvatore Di Fazio

Tnx Dennis,
this is my first python program, so I don't know every modules :(

Anyway thank you so much for the suggestions, corrections and for the
whole program :)

Thank you
 
S

Salvatore Di Fazio

Hi Dennis,
I have another little problem with your source:

Traceback (most recent call last):
File "main.py", line 86, in <module>
kdi.join() # wait for kdi thread to exit NO CPU HOG BUSY LOOPS
File "d:\programmi\python25\lib\threading.py", line 549, in join
assert self.__started, "cannot join thread before it is started"
AssertionError: cannot join thread before it is started

I don't know what this means.
Now I try some experiment.
Tnx
 
D

Dennis Lee Bieber

Hi Dennis,
I have another little problem with your source:

Traceback (most recent call last):
File "main.py", line 86, in <module>
kdi.join() # wait for kdi thread to exit NO CPU HOG BUSY LOOPS
File "d:\programmi\python25\lib\threading.py", line 549, in join
assert self.__started, "cannot join thread before it is started"
AssertionError: cannot join thread before it is started
Ah, sorry... Warned you that I didn't test...

Duplicate the block of lines with the .join() calls. Put this block
just before them, but after the threading.Thread calls, and change the
..join() to .start()
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
S

Salvatore Di Fazio

Dennis Lee Bieber ha scritto:
Ah, sorry... Warned you that I didn't test...

Duplicate the block of lines with the .join() calls. Put this block
just before them, but after the threading.Thread calls, and change the
.join() to .start()

Tnx Dennis I resolved yesterday after the post.
I tried to delete the post :)
Anyway tnx
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top