Home > Python > PythonでMultiThreadServer

PythonでMultiThreadServer

  • 2006-12-06 (Wed) 4:36
  • Python
  • hatena button
  • hatena count
  • save this page del.icio.us

文字列処理を頻繁に行う+OSネイティブのマルチスレッドを使いたいという要求から、Pythonをいじってみました。題材としてはThread Pooling型のMultiThreadServerです。

大体以下のような感じになりました。


import sys
import os
from threading import *
from socket import *
from signal import *

class PyWorkerThread(Thread):
    def __init__(self, server_sock, accept_mutex, process_func):
        self.server_sock  = server_sock
        self.accept_mutex = accept_mutex
        self.process_func = process_func
        return

    def run(self):
        server_sock  = self.server_sock
        accept_mutex = self.accept_mutex
        process_func = self.process_func
        while 1:
            accept_mutex.acquire()
            (sock, fromaddr) = server_sock.accept()
            accept_mutex.release()
            sock.settimeout(30)
            process_func(sock)
            sock.close()
        return

class PyMultiThreadServer:
    def __init__(self, port):
        signal(SIGPIPE, SIG_IGN)
        self.sock = self.createServerSock(port)
        self.threads = []
        self.accept_mutex = Lock()
        for i in range(0, 20):
            th = PyWorkerThread(self.sock, self.accept_mutex, self.process)
            self.threads.append(th)
        return

    def start(self):
        for th in self.threads:
            th.start()
        for th in self.threads:
            th.join()
        return

    def createServerSock(self, port):
        sock = socket(AF_INET, SOCK_STREAM)
        sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
        sock.bind((gethostname(), port))
        sock.listen(5)
        return sock

    def process(self, sock):
        sock.send("aiueo\n")
        return

if __name__ == "__main__":
    s = PyMultiThreadServer(40000)
    s.start()

PyWorkerThreadが個々のリクエストを裁くスレッドオブジェクトで、PyMultiThreadServerが複数個のPyWorkerThreadをPoolingしているサーバーです。はまった所としては、Thread.start()の代わりにThread.run()を使用してしまいThread切り替えが全く行われなかった点です。これはGoogle先生に助けてもらって解決しました。

PyMultiThreadServerを継承 & process関数を再実装して使います。「できたー」と喜んでいたらちゅんさんSocketServerというのが有るというのを知らされました。あらら。しかしこの辺がブラックボックス化されてるのは非常に気持ち悪いので自分のを使うことにします。

Rubyと比べると、classメンバにprivate等のアクセス権を指定できなかったり、selfが氾濫したり、アンダースコアが氾濫する点が気持ち悪いように感じます。しかしインデントが強制される事によって汚いコードが書けなくなるので(油断するとインデントが物凄く深くなって自ずと関数に分けたくなる)これはこれで良い気がします。

Thread pooling型のサーバーについていつも気になるのが、accept(2)をthread内で呼び出す際にaccept_mutexで保護する必要が有るのかどうかという点です。全スレッドが一斉にaccept(2)しに行くとプログラム全体がブロックするのでmutexで囲むべしとRichard Stevens本(Unix Network Programming)に書いてあった気がするのですが、accept(2)自体がスレッドセーフという噂もあります…。誰か詳しい人がいたら是非教えて下さい…。

[参考]
Python at Google.notes

Similar Posts:

Comments:0

Comment Form
Remember personal info

Trackbacks:0

Trackback URL for this entry
http://kzk9.net/blog/2006/12/pythonmultithreadserver.html/trackback
Listed below are links to weblogs that reference
PythonでMultiThreadServer from moratorium

Home > Python > PythonでMultiThreadServer

お薦め本
広告
Archives
Categories

Return to page top