溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

django多線程是什么

發(fā)布時(shí)間:2020-09-08 14:24:31 來(lái)源:億速云 閱讀:155 作者:小新 欄目:編程語(yǔ)言

這篇文章將為大家詳細(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ò),可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(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)容。

AI