一脚踏两船,在程序中是可以实现的。利用python的多线程并发实现多个线程并行执行。甚至可以踏N船!
# -*- coding:utf-8 -*-
import threading
class MyThread(object):
def __init__(self, func_list=None):
#所有线程函数的返回值append
self.reps = list()
self.func_list = func_list
self.threads = []
def set_thread_func_list(self, func_list):
"""
@note: func_list是一个list,每个元素是一个dict,有func和args两个参数
"""
self.func_list = func_list
def start(self):
"""
@note: 启动多线程执行,并阻塞到结束
"""
self.threads = []
self.reps = list()
for func_dict in self.func_list:
if func_dict["args"]:
new_arg_list = []
new_arg_list.append(func_dict["func"])
for arg in func_dict["args"]:
new_arg_list.append(arg)
new_arg_tuple = tuple(new_arg_list)
t = threading.Thread(target=self.trace_func, args=new_arg_tuple)
else:
t = threading.Thread(target=self.trace_func, args=(func_dict["func"],))
self.threads.append(t)
for thread_obj in self.threads:
thread_obj.start()
for thread_obj in self.threads:
thread_obj.join()
def ret_value(self):
"""
@note: 所有线程函数的返回值
"""
return self.reps
def trace_func(self, func, *args, **kwargs):
"""
@note:替代profile_func,新的跟踪线程返回值的函数,对真正执行的线程函数包一次函数,以获取返回值
"""
ret = func(*args, **kwargs)
self.reps.append(ret)
return self.reps
import time
def send(result, id):
if id in (1,2,4):
time.sleep(id*2)
result["ERROR"].append(id)
else:
result["OK"].append(id)
print "id:%s, result:%s" % (id, str(result))
def test():
print "start test"
result = {"OK": [], "ERROR": []}
g_func_list = []
mt = MyThread()
for i in range(15):
g_func_list.append({"func": send, "args": (result, i)})
mt.set_thread_func_list(g_func_list)
mt.start()
print "end test"
if __name__ == "__main__":
test()
但刚刚看了《Python源码剖析》第15章多线程机制,其实Python为了实现多线程机制,使用了GIL(Global Interpreter Lock)锁来控制多线程的同步,所以:
1. 因为同一时刻只有一个线程获得此锁,而从获取到了Python虚拟机的运行权利,所以,多核对于Python显得无用!
2. Python多线程的调度机制:(否则线程之间就成了串行运行了)
(1)运行100条指令后调度下一个线程
(2)调度哪个线程运行由操作系统决定(这就是为什么Python线程是原生线程了)
(3)阻塞调度(遇到sleep等之类的东东)不重置100数值
3. GIL默认情况下是不开启的,只有用户调用了多线程才会生成此GIL锁。