spider93286
spider93286

Reputation: 57

Threads not running simultaneously. (Python)

In Python using the threading module, my program will not run the 2 threads I created simultaneously. I am trying to create an instant message program using P2P, and I don't know if the problem is to do with the socket module or I am doing something wrong. Code:

import socket
import threading

class Receiver:
    def __init__(self):

        # Create socket that supports IPv4, TCP Protocol
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        print "Socket created."
        # Requests for IP of host (DNS)
        dns = "localhost"
        HOST = ''
        PORT = 57492
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind((HOST, PORT)) # Listens on all interfaces...
        print 'Listening on port 25565'
        s.listen(True) # Listen on the newly created socket... 
        conn, addr = s.accept()
        print 'Connected in port 25565'
        global data
        while 1:
            data = conn.recv(1024)
            print data
        s.close()

    def Sender(self):

        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        dns = "localhost"
        HOST = socket.gethostbyname(dns)
        PORT = 57492    
        # Connect to server
        s.connect((HOST, PORT))

        print "Socket connected to " + dns + " on IP " + HOST

        while 1:

            # Assign message to be sent to server to a variable
            message = raw_input("Message to be sent to server: ")

            #Send the actual message to server
            s.sendall(message)
        print "Message sent successfully"
        s.close()
    def go(self):

        th1 = threading.Thread()
        th2 = threading.Thread(target=self.Sender)
        th1.start()
        th2.start()

t = Receiver()
t.go()

Upvotes: 3

Views: 1970

Answers (3)

erewok
erewok

Reputation: 7835

These lines:

th1 = threading.Thread()
th2 = threading.Thread(target=self.Sender)

th1 has no operations to run.

Another point of concern is that you have a global variable data, and if you really plan to run this whole class multiple times, your multiple threads are probably going to clobber that variable and give you junk results. Or, were you planning to run Sender and Receiver simultaneously? The answer there with what you have is to probably pass th1 the parameter of target=self, but that seems like a terrible way to run a threaded application (a thread inside a thread?).

If the latter, you are probably better off separating Sender and Receiver into separate methods and setting up your threads to target these separate methods:

class Conversation:
    def __init__(self):
        pass

    def receiver(self):
        ...code code code...

    def sender(self):
        ...code code code...

    def go(self):

        th1 = threading.Thread(target=self.receiver)
        th2 = threading.Thread(target=self.render)
        th1.start()
        th2.start()

I don't know if this would completely solve your problem, but it's a start: it makes it so that th1 has something to do.

I also think you're also going to need some thread-safe way to tell your loops to end.

Lastly, keep you in mind you won't be able to safely pass data back and forth between these threads (if that's your intention) with the code as it currently stands.

Upvotes: 0

gsteff
gsteff

Reputation: 4942

There are two problems here. First, th1 is never given a method to execute, and so when you call start on it, the thread does nothing and exits immediately. The second problem is that you're doing permanent work (an infinite while loop) inside the constructor of the Receiver class. That means that the line t = Receiver() will (basically) never return, and you'll never get to call go().

Here's an example, with all the socket stuff removed, of how to start two threads in basic framework you've setup:

#!/usr/bin/python

import threading
import time
import signal

class Communicator:
    def __init__(self):
        self.__stop = False

    def __runSender(self):
        # setup sender here
        while not self.__stop:
            # run sender loop here
            print "in sender"
            time.sleep(1)
        print "stopped sender"

    def __runReceiver(self):
        # setup receiver here
        while not self.__stop:
            # run recevier loop here
            print "in receiver"
            time.sleep(1)
        print "stopped receiver"

    def start(self):
        senderThread = threading.Thread(target=self.__runSender)
        receiverThread = threading.Thread(target=self.__runReceiver)
        senderThread.start()
        receiverThread.start()
    def stop(self):
        self.__stop = True


c = Communicator()

def handleKill(n, frame):
    print "HANDLING SIGNAL"
    c.stop()

signal.signal(signal.SIGINT, handleKill)
print "Starting communication, hit CTRL-c to stop"
c.start()
signal.pause()

Upvotes: 1

KoffeinFlummi
KoffeinFlummi

Reputation: 1

The Sender and go methods aren't indented and therefore not part of Receiver which means that when you define th2 there is no self.Sender.

Upvotes: 0

Related Questions