한 번에 최대 3 개의 요청을 처리하는 서버를 실행해야합니다. 내 디자인은 TCP 서버가 실행 중이고이 요청을 처리하기 위해 3 개의 스레드가 실행 중입니다. 서버는 요청을 받아들이고 해당 요청을 해당 대기열을 사용하여 스레드에 전달합니다. 큐에 적절한 잠금 장치가 있습니다. 내 문제는 비록 메인 프로세스가 플래그를 사용하여 종료해야 할 때 스레드에게 신호를 보내도록 시그널 핸들러를 가지고있다. 나는 정상적인 종료가 예상대로 일어나지 않기 때문에 오류가 무엇인지 이해하지 못하고있다. 출력은 다음과 같습니다TCP 쓰레드 파이썬 서버가 예상대로 신호를 처리하지 않습니다.
vm:~/Desktop$ python multi_threaded_queueing.py
About to kickoff
About to kickoff
Starting Thread-1
About to kickoff
Starting Thread-2
Starting Thread-3
^CTraceback (most recent call last):
File "multi_threaded_queueing.py", line 94, in <module>
conn, addr = s.accept()
File "/usr/lib/python2.7/socket.py", line 202, in accept
sock, addr = self._sock.accept()
socket.error: [Errno 4] Interrupted system call
코드는 다음과 같습니다 :
#!/usr/bin/python
import Queue
import threading
import time
import sys
import socket
import signal
HOST = '127.0.0.1'
PORT = 50007 # Arbitrary non-privileged port
s = None
exitFlag = 0
#signal handler for control C
def signal_handler(signal, frame):
print "Control+C has been pressed"
#setting the exit flag so that all the threads can get notified
exitFlag = 1
#wait till all the threads have finished processing and can gracefully exit
#I maintain an array for each thread to set the corresponding index when
#it has finished its processing. I and all the elements to see if its 0
#and based on which I will exit or wait
while 1:
num = 0
for ele in exitList:
num &= ele
if ele == 0:
sys.exit(0)
class myThread (threading.Thread):
#have a queue, thread ID and name for every thread.
def __init__(self, threadID, name, q):
threading.Thread.__init__(self)
self.threadID = threadID
self.name = name
self.q = q
def run(self):
print "Starting " + self.name
process_data(self.name, self.q, self.threadID)
print "Exiting " + self.name
def process_data(threadName, q, threadID):
#while exit flag is not set by the main thread keep processing the data
#present in the queue.
while not exitFlag:
queueLock[threadID].acquire()
if not workQueue[threadID].empty():
data = q[threadID].get()
queueLock[threadID].release()
print "%s processing %s" % (threadName, data)
else:
queueLock[threadID].release()
time.sleep(1)
exitThread[threadID] = 1
threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
queueLock = []
workQueue = []
threads = []
threadID = 0
exitList = []
size = 3
request = 0
signal.signal(signal.SIGINT, signal_handler)
# Create new threads
#by default hard coding the number of threads to 3
for tName in threadList:
workQueue.append(Queue.Queue(10))
queueLock.append(threading.Lock())
exitList.append(0)
thread = myThread(threadID, tName, workQueue)
print "About to kickoff"
thread.start()
threads.append(thread)
threadID += 1
for res in socket.getaddrinfo(HOST, PORT, socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE):
af, socktype, proto, canonname, sa = res
try:
socket.setdefaulttimeout(10)
s = socket.socket(af, socktype, proto)
except socket.error, msg:
s = None
continue
try:
s.bind(sa)
s.listen(1)
except socket.error, msg:
s.close()
s = None
continue
break
if s is None:
print 'could not open socket'
sys.exit(1)
while 1:
conn, addr = s.accept()
print 'Connected by', addr
request += 1
#round robin scheduling for each thread
thread_index = request % size
while 1:
data = conn.recv(1024)
if not data: break
# Fill the queue with the request received
queueLock[thread_index].acquire()
for word in nameList:
workQueue[thread_index].put(word)
queueLock[thread_index].release()
# Wait for queue to empty
while not workQueue[thread_index].empty():
pass
conn.send(data)
conn.close()
# Notify threads it's time to exit
exitFlag = 1
print "setting the exitFlag"
# Wait for all threads to complete
for t in threads:
t.join()
print "Exiting Main Thread"
스레드 대신 다중 처리 (프로세스)를 사용해 보셨습니까? 서로 다른 스레드에서 여러 호출을 수락 할 수는 없습니다. 다중 처리 모듈을 사용하면 별도의 실행 환경에서 세 가지 프로세스를 수행 할 수 있습니다. –