Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我可以通过使部分登录服务应用程序异步来提高其响应时间吗?_Python_Sqlite_Security_Asynchronous_Tornado - Fatal编程技术网

Python 我可以通过使部分登录服务应用程序异步来提高其响应时间吗?

Python 我可以通过使部分登录服务应用程序异步来提高其响应时间吗?,python,sqlite,security,asynchronous,tornado,Python,Sqlite,Security,Asynchronous,Tornado,我刚刚写了用户登录和注销,但我试图找出最正确的方法是什么。从文档来看,似乎有一些方法可以使某些代码异步,我真的需要这样做吗?我已经包括了散列函数(我从stackoverflow获得的),所以这是完整的,可以为非常简单的应用程序构建 import os import sqlite3 import hashlib import binascii from tornado.ioloop import IOLoop from tornado.web import Application, Request

我刚刚写了用户登录和注销,但我试图找出最正确的方法是什么。从文档来看,似乎有一些方法可以使某些代码异步,我真的需要这样做吗?我已经包括了散列函数(我从stackoverflow获得的),所以这是完整的,可以为非常简单的应用程序构建

import os
import sqlite3
import hashlib
import binascii
from tornado.ioloop import IOLoop
from tornado.web import Application, RequestHandler
from tornado.options import define, options


define('port', default=80, help='port to listen on')

settings = dict(
    template_path=os.path.join(os.path.dirname(__file__), "templates"),
    static_path=os.path.join(os.path.dirname(__file__), "static"),
    debug=True,
    cookie_secret="changethis",
    login_url="/login",
    # xsrf_cookies=True,
)

def hash_password(password):
    """Hash a password for storing."""
    salt = hashlib.sha256(os.urandom(60)).hexdigest().encode('ascii')
    pwdhash = hashlib.pbkdf2_hmac('sha512', password.encode('utf-8'), 
                                salt, 100000)
    pwdhash = binascii.hexlify(pwdhash)
    return (salt + pwdhash).decode('ascii')

def verify_password(stored_password, provided_password):
    """Verify a stored password against one provided by user"""
    salt = stored_password[:64]
    stored_password = stored_password[64:]
    pwdhash = hashlib.pbkdf2_hmac('sha512', 
                    provided_password.encode('utf-8'), 
                    salt.encode('ascii'), 100000)
    pwdhash = binascii.hexlify(pwdhash).decode('ascii')
    return pwdhash == stored_password

try:
    db = sqlite3.connect('file:aaa.db?mode=rw', uri=True)
except sqlite3.OperationalError:
    db = sqlite3.connect("aaa.db")
    db.execute("CREATE TABLE Users (id INTEGER PRIMARY KEY, username TEXT NOT NULL UNIQUE, password TEXT NOT NULL);")

class BaseHandler(RequestHandler):
    def get_current_user(self):
        return self.get_secure_cookie("session")

class IndexHandler(BaseHandler):
    def get(self):
        if not self.current_user:
            self.write("not logged in")
            return
        count = db.execute("SELECT COUNT(*) FROM Users;").fetchone()
        self.write('{} users so far!'.format(count[0]))

class LoginHandler(BaseHandler):
    def get(self):
        if self.current_user:
            self.write("already logged in")
            return
        self.render("login.html")
    def post(self):
        if self.current_user:
            self.write("already logged in")
            return
        name=self.get_body_argument("username")
        query= db.execute("SELECT COUNT(*) FROM Users WHERE username = ?;", (name,)).fetchone()
        if query[0] == 0:
            self.write("user does not exist")
        else:
            hashed_password = db.execute("SELECT (password) FROM Users WHERE username = ?;", (name,)).fetchone()[0]
            if verify_password(hashed_password, self.get_body_argument("password")):
                self.set_secure_cookie("session", name)
                self.write("cookie set, logged in")
            else:
                self.write("wrong password")

class SignupHandler(BaseHandler):
    def get(self):
        if self.current_user:
            self.write("already logged in")
            return
        self.render("signup.html")
    def post(self):
        if self.current_user:
            self.write("already logged in")
            return
        name=self.get_body_argument("username")
        password=self.get_body_argument("password")
        try:
            with db:
                db.execute("INSERT INTO Users(username,password) VALUES (?,?);", (name, hash_password(password)))
        except sqlite3.IntegrityError:
            self.write("user exists")
            return
        self.write("user added")

class LogoutHandler(BaseHandler):
    def get(self):
        self.clear_cookie("session")
        self.write("logged out")

def main():
    routes=(
            (r'/', IndexHandler),
            (r'/login', LoginHandler),
            (r'/logout', LogoutHandler),
            (r'/signup', SignupHandler),
        )
    app = Application(routes, **settings)
    app.listen(options.port)
    IOLoop.current().start()

if __name__=="__main__":
    main()

简短回答:否。

异步代码不会让事情变得“更快”。异步代码只是普通的同步代码,具有一些暂停/恢复操作的额外功能。没有速度增益。异步代码的目的不是速度,而是在不增加线程开销的情况下实现并发性


请参见以下代码中的这两个函数:

def func1():
    data = get_data_from_database()
    return data


async def func2():
    data = await get_data_from_database()
    return data
func1
是同步的,
func2
是异步的。这两个函数的速度相同,因为它们都必须等待数据库返回数据

因此,您可以使代码异步,但这不会导致任何速度提高,因为数据库将以正常速度返回数据,只有在这之后,您的代码才能执行进一步的操作


不要在Tornado中使用SQLite。它在与Tornado代码相同的Python进程中运行。而且,由于它将向磁盘读写数据,这将导致较慢的阻塞代码,这将阻塞整个Tornado服务器,并导致性能低下。有关“阻塞代码”的解释,请参见下文

现在,是的,您可以通过在单独的线程中运行它来实现异步,但是为什么不首先使用独立的数据库,比如PostgreSQL或MySQL呢


阻塞代码

阻止程序进一步移动或执行任何其他操作的代码称为阻塞代码

阻止代码可以是以下任何类型:

  • 网络绑定操作。例如,您正在发出http请求或数据库请求,这是一个绑定到网络的操作,速度较慢。这会导致代码阻塞,因为在得到响应之前,代码无法向前移动
  • 磁盘绑定操作。例如,如果从磁盘读取文件,则会导致代码阻塞,因为如果磁盘忙或慢,则代码在从磁盘获取数据之前无法向前移动
  • CPU限制的操作。例如,执行非常繁重的计算会占用大量CPU时间。它将导致代码阻塞,因为在从CPU获得计算结果之前,代码无法向前移动

  • 异步代码对于网络绑定操作非常有用。对于磁盘和CPU绑定的操作,同步代码更好

    请尽量提高你的问题的重点,以便在这里回答。如果你想让别人看你的代码,你有什么建议吗?我将把我的代码带到那里,我应该在这里留下什么?也许您可以问“我可以通过使部分登录服务应用程序异步来提高其响应时间吗?”这只是一个想法。似乎你得到的很多东西都是“这段代码对……足够好吗?”。除了指出突出的问题外,这些问题的答案往往是推测性的和基于观点的,这与本网站的主题无关,