以前没写过多线程和多进程的笔记,自己抽空写了个实例,网上大多数的例子都是一样的,翻了百度几页都是几个计数器加时间打印出来,一般初学者也是很难看懂的
Python解释器由于设计时有GIL全局锁,导致了多线程无法利用多核,实际使用的是单核CPU,使用抢占模式来执行任务,实际没有并行处理任务,所以实际场景当中和单线程没有太大的速度上的效果,同时多线程使用的资源都有所有线程来共享,所以我们再使用资源的时候需要加锁,以免当前线程修改资源的时候其他线程也来修改导致把数据改乱,我下面例子场景由于是中使用了queue队列,所以无需加锁来操作
主要代码如下:
#!/usr/bin/python3 #coding:utf-8 from queue import Queue from threading import Thread import pymysql import time q = Queue() def get_conn(): conn = False try: conn = pymysql.Connect(host='127.0.0.1', port=3306, user='root', passwd='Zero20ba', db='sulao', charset='utf8') except: print("Connect MySQL failed !") conn = False return conn def get_data(sql): cur = get_conn().cursor() cur.execute(sql) data = cur.fetchall() return data def add_queue(data): for p in data: q.put(p) return q def build_file(_queue): while _queue.qsize() > 0: try: task = _queue.get() with open("html/%s.html" % task[0], 'w', encoding='utf-8') as f: html = """ <html> <meta charset='utf-8' /> <title>%s</title> <body> %s </body> </html> """ % (task[1], task[2]) f.write(html) _queue.task_done() except: print("%s , Write failed !" % task[1]) if __name__ == "__main__": start_time = time.time() sql = """SELECT `log_ID`,`log_Title`,`log_Content` FROM `zbp_post` WHERE `log_Status`=0 ORDER BY `log_ID` ASC""" data = get_data(sql) print("总共 %d 条数据" % len(data)) _queue = add_queue(data) threads = [] for k in range(4): t = Thread(target=build_file, args=(_queue,)) print("这是第 %d 进程 " % k) threads.append(t) for ts in threads: ts.start() ts.join() _queue.join() end_time = time.time() print("耗时 %.3f " % (end_time - start_time))
因为数据不是很多,起线程都需要一定时间,所以这里创建4个线程以后处理程序的速度还没单个线程快,还有是由于GIL锁导致的,线程间不是并行,线程交替执行,上下文切换等导致了多线程比单线程还慢