我需要运行一个服务器,一次最多处理 3 个请求。我的设计是我有一个 TCP 服务器正在运行,并且将运行 3 个线程来处理这些请求。服务器将接受请求并将这些请求传递给使用相应锁队列的线程。我也有适当的队列锁。我的问题是,即使我有一个信号处理程序来在主进程必须退出时使用标志向线程发出信号。我不明白错误是什么,因为它没有按预期正常退出。输出结果如下:
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"
最佳答案
有几件事情正在发生。
signal_handler(signal, frame): 未设置全局 exitFlag。您需要将 global exitFlag 添加到函数的顶部。
sys.exit() 并没有真正退出 - 它只是引发了一个 KeyboardInterrupt 错误。
socket.error: [Errno 4] Interrupted system call 是个好东西,它可以防止您的程序卡在 conn, addr = s.accept()。您应该捕获 socket.error 异常并使用它们来跳出 while 循环。
关于python - TCP 线程 python 服务器未按预期处理信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27612149/
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru
在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
您如何在Rails中的实时服务器上进行有效调试,无论是在测试版/生产服务器上?我试过直接在服务器上修改文件,然后重启应用,但是修改好像没有生效,或者需要很长时间(缓存?)我也试过在本地做“脚本/服务器生产”,但是那很慢另一种选择是编码和部署,但效率很低。有人对他们如何有效地做到这一点有任何见解吗? 最佳答案 我会回答你的问题,即使我不同意这种热修补服务器代码的方式:)首先,你真的确定你已经重启了服务器吗?您可以通过跟踪日志文件来检查它。您更改的代码显示的View可能会被缓存。缓存页面位于tmp/cache文件夹下。您可以尝试手动删除
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。