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解释器会认为你是在创建一个新的局部变量。
 

11-04 10:55