关于python async和await的使用,我已经尝试了一个星期了
async def updateAdventureCnt():
conn = pymysql.connect(host=HOST,db = DB ,user=USER, passwd=PAWD, port=0, charset="utf8", init_command="SET NAMES utf8")
cur = conn.cursor()
print("database to connect successfully.")
sql = '''
select char_oid,expedition_point,cur_adventure_cnt FROM char_data
'''
cur.execute(sql) # 执行sql语句
conn.commit() # 提交到数据库执行
rows = cur.fetchall()
for row in rows:
expediton_point = row[1]
if expediton_point > 0:
char_oid = row[0]
cur_adventure_cnt = row[2] + expediton_point * 3
UpdateSql = '''
UPDATE char_data SET cur_adventure_cnt=%d where char_oid = %d
''' % (cur_adventure_cnt, char_oid)
cur.execute(UpdateSql)
conn.commit()
# return 'update ok'
# cur.close() # 关闭数据库
# conn.close()
上图代码是简单的同步刷mysql数据可的代码,代码运行没有问题,使用async声明此函数为协程函数。
async def test1():
a = time.time()
r = await updateAdventureCnt()
print(time.time()-a)
print('线程是',threading.currentThread())
print(r)
这里又加装了一层协程函数,是为了打印,方便我看出来是否是异步运行
loop = asyncio.get_event_loop()
tasks = [test1(),test1()]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
这里是实际运行,我对此操作数据库的函数运行了两次
database to connect successfully.
3.461343288421631
线程是 <_MainThread(MainThread, started 3728)>
None
database to connect successfully.
3.5280568599700928
线程是 <_MainThread(MainThread, started 3728)>
None
这里是实际运行结果
通过以上,明显可以看出来,我仍然是在同步运行,并没有起到异步的效果,白白声明了几个协程函数,和使用AWAIT等待结果。
而我的本意是希望在我操作数据库,在阻塞的时候(例如提交和等待结果),跳过这个阻塞,去运行另一个操作数据库的任务,直到第一个任务返回结果,继续运行,这应该才是异步的操作。
我想知道我上面的代码,究竟是什么地方出现了问题,导致我不能达到异步的效果,
而我自己的猜测,
第一个原因我的数据库操作都是阻塞运行的,所以导致代码一直从上往下运行了两遍。但是我能力有限,没办法使用await或者其他办法来使这些IO非阻塞,并等待结果返回。
如果是这个原因导致程序无法运行的,我希望有人能帮我解决,或者书写一个简单的示例,这个示例我不希望是使用了各种异步库的,因为这些异步库本身已经进行了协程的封装,他们前面是可以合理使用await使其非阻塞和等待结果的,这个我是知道的,而我疑惑的是,如果我自己要书写一个例如asyncio.sleep(10) 一样的函数,使其可以await非阻塞,有了结果会回调,会很麻烦吗。
第二个原因
loop.run_until_complete(asyncio.wait(tasks))
是否我运行的方式不正确?