您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)django多線程是什么,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。
在一段完整的代碼中,往往會(huì)有需要獨(dú)立的代碼模塊,而這些獨(dú)立運(yùn)行的程序片段叫作“線程”(Thread),利用多個(gè)線程編程的概念就叫作多線程處理(多線程編程),多線程是為了同步完成多項(xiàng)任務(wù),不是為了提高運(yùn)行效率,而是為了提高資源使用效率來(lái)提高系統(tǒng)的效率。多線程是在程序在同一時(shí)間需要完成多項(xiàng)任務(wù)的時(shí)候?qū)崿F(xiàn)的。多線程的目的僅僅是為了提高資源利用效率。各個(gè)線程執(zhí)行自己的任務(wù),這些線程可以”同時(shí)進(jìn)行“。同時(shí)進(jìn)行并非同一時(shí)刻進(jìn)行,而是在某一時(shí)間段內(nèi),完成所有任務(wù),任務(wù)的運(yùn)行有先后順序。
簡(jiǎn)單的說(shuō)就是服務(wù)端監(jiān)聽 socket 每次 accept 一個(gè)新的請(qǐng)求后,開一個(gè)線程處理 這個(gè) socket 客戶連接。如果你對(duì)底層實(shí)現(xiàn)原理感興趣,可以繼續(xù)看下去,從 socket 編程的角度來(lái)解釋多線程 wsgi server。最后附上一個(gè)異步框架工作過(guò)程的視頻講解。這里我們自己擼一個(gè)簡(jiǎn)單的多線程 wsgi server 來(lái)看下原理,還是需要深入源碼和 socket 編程你才能真正理解。 我們從 python 自帶的一個(gè) wsgi server 看下如何實(shí)現(xiàn)多線程處理請(qǐng)求。首先你需要熟悉下 wsgi。 看一個(gè)最簡(jiǎn)單的 wsgi app:
def application(environ, start_response): status = '200 OK' headers = [('Content-Type', 'text/html; charset=utf8')] start_response(status, headers) return [b"<h2>Hello</h2>"]if __name__ == '__main__': from wsgiref.simple_server import make_server httpd = make_server('127.0.0.1', 8000, application) httpd.serve_forever()
然后用你的開發(fā)工具跟進(jìn)去 make_server 這個(gè)函數(shù),看下它的定義:
def make_server( host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler): """Create a new WSGI server listening on `host` and `port` for `app`""" server = server_class((host, port), handler_class) server.set_app(app) return serverclass WSGIServer(HTTPServer): """BaseHTTPServer that implements the Python WSGI protocol""" application = None def server_bind(self): """Override server_bind to store the server name.""" HTTPServer.server_bind(self) self.setup_environ() def setup_environ(self): # Set up base environment env = self.base_environ = {} env['SERVER_NAME'] = self.server_name env['GATEWAY_INTERFACE'] = 'CGI/1.1' env['SERVER_PORT'] = str(self.server_port) env['REMOTE_HOST']='' env['CONTENT_LENGTH']='' env['SCRIPT_NAME'] = '' def get_app(self): return self.application def set_app(self,application): self.application = application
看到這個(gè) WSGIServer 定義了嗎,繼承了一個(gè) HttpServer。我們?cè)倮^續(xù)追一下其定義:
class HTTPServer(SocketServer.TCPServer): allow_reuse_address = 1 # Seems to make sense in testing environment def server_bind(self): """Override server_bind to store the server name.""" SocketServer.TCPServer.server_bind(self) host, port = self.socket.getsockname()[:2] self.server_name = socket.getfqdn(host) self.server_port = port
到這里,我們繼續(xù)追,看到 TcpServer 定義:
class TCPServer(BaseServer): """這里我省略了定義"""
你還可以發(fā)現(xiàn)一個(gè) ThreadingTCPServer 類:我們看下它的定義
class ThreadingTCPServer(ThreadingMixIn, TCPServer): pass
好了,怎么多線程處理請(qǐng)求呢?看下這個(gè) ThreadingMixIn 類是如何實(shí)現(xiàn)的:
class ThreadingMixIn: """Mix-in class to handle each request in a new thread.""" # Decides how threads will act upon termination of the # main process daemon_threads = False def process_request_thread(self, request, client_address): """Same as in BaseServer but as a thread. In addition, exception handling is done here. """ try: self.finish_request(request, client_address) self.shutdown_request(request) except: self.handle_error(request, client_address) self.shutdown_request(request) def process_request(self, request, client_address): """Start a new thread to process the request.""" t = threading.Thread(target = self.process_request_thread, args = (request, client_address)) t.daemon = self.daemon_threads t.start()
看到嗎,其實(shí)就是對(duì)于每個(gè)新請(qǐng)求,會(huì)啟動(dòng)一個(gè)新的線程來(lái)處理 socket 請(qǐng)求。假如讓我們自己實(shí)現(xiàn)一個(gè)多線程 socket server 應(yīng)該怎么實(shí)現(xiàn)呢?先來(lái)寫一個(gè)簡(jiǎn)單的單線程 socker echo server:
from socket import * # 偷懶這么寫s = socket(AF_INET, SOCK_STREAM)s.bind(("", 9000))s.listen(5)while True: c, a = s.accept() print "Received connection from", a c.send("Hello %s\\n" % a[0]) c.close()
關(guān)于django多線程是什么就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。