1 只用实时最新数据 使用共享变量+lock
import threading
import time
# 创建全局变量来存储数据
data1 = None
data2 = None
data3 = None
# 创建锁
lock1 = threading.Lock()
lock2 = threading.Lock()
lock3 = threading.Lock()
def thread1():
global data1
while True:
# 获取日K线数据,并放入全局变量
with lock1:
data1 = get_daily_data()
time.sleep(86400) # 每日执行一次
def thread2():
global data2
while True:
# 获取实时数据,并放入全局变量
with lock2:
data2 = get_realtime_data()
time.sleep(1) # 每秒执行一次
def thread3():
while True:
# 处理data1和data2,形成data3
with lock1, lock2, lock3:
if data1 is not None and data2 is not None:
data3 = process_data(data1, data2)
time.sleep(1) # 每秒执行一次
def thread4():
global data3
while True:
# 根据data3下单
with lock3:
if data3 is not None:
place_order(data3)
time.sleep(1) # 每秒执行一次
# 创建并启动线程
t1 = threading.Thread(target=thread1)
t2 = threading.Thread(target=thread2)
t3 = threading.Thread(target=thread3)
t4 = threading.Thread(target=thread4)
t1.start()
t2.start()
t3.start()
t4.start()
# 等待所有线程结束
t1.join()
t2.join()
t3.join()
t4.join()
2 使用每一个时序数据 要用队列(生产者消费者)
import threading
import time
import queue
# 创建一个线程安全的队列来存储数据
data1 = queue.Queue()
data2 = queue.Queue()
data3 = queue.Queue()
def thread1():
while True:
# 获取日K线数据data,并放入队列
data1.put(data)
time.sleep(86400) # 每日执行一次
def thread2():
while True:
# 获取实时数据data,并放入队列
data2.put(data)
time.sleep(1) # 每秒执行一次
def thread3():
while True:
# 处理data1和data2,形成data3
if not data1.empty() and not data2.empty():
data3.put(data)
time.sleep(1) # 每秒执行一次
def thread4():
while True:
# 根据data3下单
if not data3.empty():
place_order(data3.get())
time.sleep(1) # 每秒执行一次
# 创建并启动线程
t1 = threading.Thread(target=thread1)
t2 = threading.Thread(target=thread2)
t3 = threading.Thread(target=thread3)
t4 = threading.Thread(target=thread4)
t1.start()
t2.start()
t3.start()
t4.start()
# 等待所有线程结束
t1.join()
t2.join()
t3.join()
t4.join()
3 多线程全局变量使用注意事项
3.1 不改变原始data1使用 df = data1.copy()
def thread3():
df = data1.copy()
3.2 要改变data1或data2
def thread3():
global data1, data2
在Python中,当你在函数内部读取变量时,Python的解释器会首先在函数的局部作用域中查找该变量。如果在局部作用域中找不到,它会在全局作用域中查找。
在你的thread3函数中,你直接使用了data1和data2,并没有试图修改它们的值,因此Python解释器会直接从全局作用域中读取这两个变量。这就是为什么你可以在没有使用global关键字的情况下读取全局变量的值。
但是,如果你试图在函数内部修改全局变量的值,你就需要使用global关键字来告诉Python解释器你想要引用的是全局变量。否则,Python解释器会认为你是在创建一个新的局部变量。
是因为我使用了df = data1.copy() ?
对的。在你的thread3函数中,你使用了df = data1.copy(),这是在创建一个新的局部变量df,它是全局变量data1的一个副本。在这个过程中,你并没有试图修改data1的值。因此,你可以在没有使用global关键字的情况下读取全局变量data1的值。
如果你试图在函数内部修改全局变量的值,例如data1 = something,你就需要使用global关键字来告诉Python解释器你想要引用的是全局变量。否则,Python解释器会认为你是在创建一个新的局部变量。