Форум сайта python.su
Вот написал пример в котором ждет себе программа когда кто то к сокету конектится. Еслиесть конект то милости просим в отдельный поток. Проблема по сабжу что потоков явно для неорганиченого числа подключений не хватает. Вопрос что делать? Давать на трэд по несколько конектов обслуживать? Заранее спасиб.
Отредактировано (Авг. 26, 2010 22:38:57)
Офлайн
Насчет неограниченного числа подключений вы явно погорячились, но используя треды, а если их будет мало, то gevent, это число можно серьезно увеличить.
Читать здесь:
http://docs.python.org/library/asyncore.html
http://docs.python.org/library/socketserver.html?highlight=tcp%20server
http://www.gevent.org/intro.html
Офлайн
Потоки как мне кажется это реальный выход. Но это попахивает идиотизмом создавать такое количество потоков. Будем копать.
Офлайн
Вот здесь http://pycon.blip.tv/file/3359630/ автор greenlet утверждает, что ему удалось создать около 1000 тредов, после чего ОС сказала ‘Извини, но я больше не буду делать тебе треды’ :)
Кстати, рекомендую посмотреть видео целиком. Очень интересно и как раз в тему.
В частности он упоминает еще одну возможность - неблокирующий ввод/вывод. Если вам так противны треды, то можете попробовать этот подход.
Офлайн
Сначала изучаем неблокирующие сокеты и select.select.
Потом, поэкспериментировав на кроликах и проникшись идеей, выбираем между более оптимальными реализациями.
Офлайн
Ed, как не странно но то же самое удалось и у меня. Это где то 1020 тредов. Видео не позволяет посмотреть мой мобильный диал-ап. Я так понял что асинхронизация + нагрузка на один тред определенного числа конектов и можно заполнять анкету в книгу рекордов. Просьба делать ссылки на хотя бы обрывки кода.
ладно оцените мой “почерк”
Сервер
#!/usr/bin/python
import socket,time,threading
HOST = 'localhost'
PORT = 5000
class OnConnect(threading.Thread):
def __init__(self,conn,addr,indexx):
threading.Thread.__init__(self)
self.conn=conn
self.addr=addr
self.indexx=indexx
self.start()
def run(self):
while 1:
try: data = self.conn.recv(1024)
except:
break
else:
if (not data) : break
self.conn.send(data)
time.sleep(0.1)
self.conn.close()
print self.indexx,'-',self.addr[0],':',self.addr[1],'(',time.asctime(time.gmtime(time.time())),')'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
print 'Run in',time.asctime(time.gmtime(time.time()))
print 'Host: ',HOST
print 'port: ',PORT
s.listen(1)
d=0
threading.stack_size(0x100000)
while 1:
conn, addr = s.accept()
d=d+1
print d,'+',addr[0],':',addr[1],'(',time.asctime(time.gmtime(time.time())),')'
OnConnect(conn,addr,d)
time.sleep(0.1)
conn.close()
import socket,threading,time
class TestServ(threading.Thread):
def __init__(self,s):
threading.Thread.__init__(self)
self.s=s
self.start()
def run(self):
for i in range(1000):
self.s.send('x')
data=self.s.recv(1024)
time.sleep(1)
self.s.send('exit')
self.s.close()
port=5000
threading.stack_size(0x100000)
for i in range(10000):
print i
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('localhost',port))
TestServ(s)
time.sleep(0.1)
Отредактировано (Авг. 27, 2010 01:31:00)
Офлайн
Посмотрите в код фреймворка/сервера Tornado и почитайте о проблеме 10k - http://www.kegel.com/c10k.html. Также познавательным будет знакомство с сервером YAWS - http://yaws.hyber.org.
Андрей СветловДавайте все-таки на кошках =)
Потом, поэкспериментировав на кроликах и проникшись идеей
Офлайн
CryptSpiritСтранно. А это точно про треды. потому что 1021 это очень похоже на ограничение по файловым дескрипторам.
Ed, как не странно но то же самое удалось и у меня. Это где то 1020 тредов.
Traceback (most recent call last):
File "./server.py", line 55, in <module>
thread.start()
File "/usr/lib/python2.6/threading.py", line 474, in start
_start_new_thread(self.__bootstrap, ())
thread.error: can't start new thread
ладно оцените мой “почерк”…
Не пинать я с апреля на питонеКак же тогда оценивать :) ?
Отредактировано (Авг. 27, 2010 14:53:22)
Офлайн
CryptSpiritВот, что у меня получилось используя eventlet monkey_patch. Это по сути аналог вашего сервера - уберите вызов monkey_patch - получите полный аналог.
Просьба делать ссылки на хотя бы обрывки кода.
import eventlet
eventlet.monkey_patch()
import sys
from threading import Thread
import socket
HOST, PORT = 'localhost', 5000
def handle(index, addr, conn):
while True:
data = conn.recv(1024)
if not data:
break
conn.send(data)
print 'client %i disconnected' % index
if __name__ == '__main__':
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((HOST, PORT))
sock.listen(1)
print 'Server is waiting for connections on %s:%d' % (HOST, PORT)
index = 0
while True:
index += 1
conn, addr = sock.accept()
print "client connected from %s:%s. Creating thread %d" % (addr[0], addr[1], index)
thread = Thread(target=handle, args=(index, addr, conn))
thread.start()
Офлайн
можно попробоват ьиспользовать селект
Офлайн