LINUX.ORG.RU

[python][select]Есть вопрос

 ,


0

1

Здравствуйте, в клиент-серверное приложение, в серверной части есть класс client содержащий информацию о клиентах и socket. Хотел бы вместо объектов сокета функции select передавать объекты класса client, но при этом не хочется создавать метод fileno в классе клиента.
В общем, мне хочется, что бы select возвращала не список сокетов готовых для чтения, а список объектов класса client у которых объект класса socket готов к чтению. Как это можно реализовать?
Спасибо!

★★★★★

A file descriptor is either a socket or file object, or a
small integer gotten from a fileno() method call on one of those.

Храни map fd -> client

phoenix ★★★★
()

хочется, что бы select возвращала не список сокетов готовых для чтения, а список объектов класса client у которых объект класса socket готов к чтению. Как это можно реализовать?

Написать свой select // К.О.

tailgunner ★★★★★
()
Ответ на: комментарий от phoenix

Можно чуть подробнее пожалуйста.

deterok ★★★★★
() автор топика
Ответ на: комментарий от deterok

я к чему его предложил. Ты явно хочешь повысить уровень абстракции кода. Так зачем себя ограничивать селектом? Есть тыща и одна либа которая предоставляет «продвинутый селект». Тот же twisted, например.

Но писать всё на коллбэках в 2012 году тупо. А gevent хоть и низкоуровневое средство, но содержит в себе всё что надо для построения абстрактного от сети кода, включая события, очереди, таймеры итд. Я думаю селект вообще не понадобится.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Здорово, буду крутить ее, разбираться, спасибо.

deterok ★★★★★
() автор топика
Ответ на: комментарий от true_admin

Хотел спросить по gevent, пока только в ней разбираюсь и не очень еще ориентируюсь. В прошлый раз хотел реализовать такую систему: есть поток, который асептит клиентов(обычная бесконечная петля, с полусекундой ожидания, если socket кинет экскепшен timeout), и есть поток обработчик. Вот 2 поток и составил для меня большую сложность, там я сделал бесконечный цикл с потоками и семафорами такого плана:

1) собираем с помощью select все сокеты готовые к чтению
2) Обходим эти сокеты циклом for
3) Если семафор не заблокирован, то в отдельном потоке запускаем обработчик которому передаем объект сокета.
4) Если семафор заблокирован, то ждем его разблокировки.
(потоков для обработчика выделял пока только 10, но в планох было в зависимости от загруженности системы, хотел бы знать ваше мнение по подобной методике, на сколько она хороша? )

Вот в этом, втором, цикле я захотел скармливать функции select не сокеты, а уже объекты клиентов.

Когда стал разбираться в gevent понял что там какая то своя, умная, петля событий на которой все построено. Вот я и подумал, может сделать такую системку:
1) Асептим клиент
2) добавляем полученный сокет в объект класса client
3) делаем gevent.spawn(handler, объект_подключенного_клиента, интерфейс_сервера)
4) Функция handler ждет до тех пор, пока сокет не будет готов к чтению
Меня смущает, что я не понимаю, что делает функция spawn, вернее как она распараллеливает все это. И можно ли для каждого клиента создать отдельный поток, и возложить всю работу на планировщик ядра? На сколько это глупо?
Да, и как правильно проверять, что клиент еще подключен и соединение с ним не оборвано?

Не пинайте сильно, я только в этом разбираюсь. Спасибо за внимание.

deterok ★★★★★
() автор топика
Ответ на: комментарий от deterok

короче, сделай так:

class Client(gevent.Greeenlet):
    def __init__(self, socket):
        gevent.Greeenlet.__init__(self)
        self.socket = socket

    def _run(self):
        while True:
            print(self.socket.recv())


class Listener(gevent.Greenlet):
     def __init__(self):
         gevent.Greeenlet.__init__(self)
         self.socket = blah-blah-blah

     def _run(self):
         while True:
            new_sock = self.socket.accept()
            client = Client(new_sock)
            client.start()


if __name__ == '__main__':
     listener = Listener()
     listener.start()
     listener.join()

код не проверял, я пьян и в отпуске (= никаких гарантий). Кстати, по-моему, в _run() можно передавать аргументы, это уже сам проверяй.

true_admin ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.