Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我可以从线程内重复调用线程吗?_Python_Multithreading_Concurrency_Queue - Fatal编程技术网

Python 我可以从线程内重复调用线程吗?

Python 我可以从线程内重复调用线程吗?,python,multithreading,concurrency,queue,Python,Multithreading,Concurrency,Queue,我试图使用队列将样本从线程A(“采集”)传输到线程B(“P300”),但我无法读取线程B中的任何数据,尽管样本正在线程A中分配。从我的输出判断,我认为线程B在线程A开始放入数据之前正在匆忙测试 请参见下面我的代码结构的近似值: import threading import queue from queue import Empty import numpy as np import warnings warnings.filterwarnings("error") cla

我试图使用
队列
将样本从线程A(“采集”)传输到线程B(“P300”),但我无法读取线程B中的任何数据,尽管样本正在线程A中分配。从我的输出判断,我认为线程B在线程A开始放入数据之前正在匆忙测试

请参见下面我的代码结构的近似值:

import threading
import queue
from queue import Empty
import numpy as np
import warnings
warnings.filterwarnings("error")

class AcqThread(threading.Thread):
    def __init__(self, dataOutQ1, dataOutQ2, stopQ1, stopQ2, saveQ):
        threading.Thread.__init__(self)
        self.stopQ2 = stopQ2
        self.stopQ1 = stopQ1
        self.dataOutQ2 = dataOutQ2
        self.dataOutQ1 = dataOutQ1
        self.saveQ = saveQ

    def run(self):
        Acquisition(inlet, self.dataOutQ1, self.dataOutQ2, self.stopQ1, self.stopQ2, self.saveQ)

class P300Thread(threading.Thread):
    def __init__(self, dataInQ, featureQ, stopQ):
        threading.Thread.__init__(self)
        self.dataInQ = dataInQ
        self.featureQ = featureQ
        self.stopQ = stopQ

    def run(self):
        P300fun(self.dataInQ, self.featureQ, self.stopQ)

threadLock = threading.Lock()
SaveQ = queue.Queue()
DataOutQ1 = queue.Queue()
DataOutQ2 = queue.Queue()
StopQ1 = queue.Queue()
StopQ2 = queue.Queue()
FeatQ1 = queue.Queue()
StopQ1.put(0)
StopQ2.put(0)
#
AcqTh = AcqThread(DataOutQ1, DataOutQ2, StopQ1, StopQ2, SaveQ)
P300Th = P300Thread(DataOutQ1, FeatQ1, StopQ1)

def Acquisition(inlet, dataOutQ1, dataOutQ2, stopQ1, stopQ2, saveQ):
    i = 0
    print('Starting...')
    while i<1250: #i is the number of samples
        sample, timestamp = inlet.pull_sample() #samples coming in @ 250Hz
        ##Normalization, filtering##
        threadLock.acquire()
        dataOutQ1.put([filtsamples[:,-250:], rawtimestamps[-250:]]) #I only need the last 250 samples
        threadLock.release()
        i += 1

def P300fun(dataInQ, featureQ, stopQ):
    p300sample = []
    p300timestamp = []
    print(f"Is DataInQ size true? {DataOutQ1.qsize()}")
    print("Is dataInQ emtpy?", DataOutQ1.empty())
    while dataInQ.qsize(): #or while not dataqueue.empty():
        try:
            print("DataInQ has data")
            ss, ts = dataInQ.get(0) 
            print('<>P300\n>>Samples [', ss, ']\nTimestamp [', ts, ']')
        except Empty:
            return
    print('Thread Finished')

if __name__ == '__main__':
    print('Looking for an EEG stream...')
    streams = resolve_stream('type', 'EEG')
    inlet = StreamInlet(streams[0])
    print('Connected!\n')

    AcqTh.start()
    P300Th.start()

    AcqTh.join()
    P300Th.join()

    print("\n\n>>>DONE<<<\n\n")
导入线程
导入队列
从队列导入空
将numpy作为np导入
进口警告
警告。过滤器警告(“错误”)
类AcqThread(threading.Thread):
定义初始化(self、dataOutQ1、dataOutQ2、stopQ1、stopQ2、saveQ):
threading.Thread.\uuuuu init\uuuuuu(自)
self.stopQ2=stopQ2
self.stopQ1=stopQ1
self.dataOutQ2=dataOutQ2
self.dataOutQ1=dataOutQ1
self.saveQ=saveQ
def运行(自):
采集(入口、self.dataOutQ1、self.dataOutQ2、self.stopQ1、self.stopQ2、self.saveQ)
P300级螺纹(螺纹.螺纹):
定义初始化(self、dataInQ、featureQ、stopQ):
threading.Thread.\uuuuu init\uuuuuu(自)
self.dataInQ=dataInQ
self.featureQ=featureQ
self.stopQ=stopQ
def运行(自):
P300fun(self.dataInQ、self.featureQ、self.stopQ)
threadLock=threading.Lock()
SaveQ=queue.queue()
DataOutQ1=队列。队列()
DataOutQ2=队列。队列()
StopQ1=queue.queue()
StopQ2=queue.queue()
FeatQ1=队列。队列()
StopQ1.put(0)
StopQ2.put(0)
#
AcqTh=AcqThread(DataOutQ1、DataOutQ2、StopQ1、StopQ2、SaveQ)
P300Th=P300线程(DataOutQ1、FeatQ1、StopQ1)
def采集(入口、dataOutQ1、dataOutQ2、stopQ1、stopQ2、saveQ):
i=0
打印('开始…')

虽然我做了成为一个noob可能很棘手。。。因此,我将回答自己的问题,以帮助其他可能遇到此问题的初学者

首先:不,不可能从线程中重复调用线程,因为每个线程只能调用一次

但是有一种方法可以防止线程结束,让它们等待允许它们继续的触发器。经过更多的研究,我发现有一种方法可以为线程创建事件。可以找到文档。这非常简单:事件对象的行为类似于标志,可以是
set()
(表示True)或
clear()
(表示False,这是原始值)。要测试事件,可以使用
is_set()
方法解决布尔问题,或者使用
wait()
方法代替计时器。就我而言,它为我节省了一些我将要使用的队列:

import threading
import queue
from queue import Empty
import numpy as np


class AcqThread(threading.Thread):
    def __init__(self, dataOutQ1, dataOutQ2, saveQ):
        threading.Thread.__init__(self)
        self.dataOutQ2 = dataOutQ2
        self.dataOutQ1 = dataOutQ1
        self.saveQ = saveQ

    def run(self):
        Acquisition(inlet, self.dataOutQ1, self.dataOutQ2, self.saveQ)

class P300Thread(threading.Thread):
    def __init__(self, dataInQ, featureQ):
        threading.Thread.__init__(self)
        self.dataInQ = dataInQ
        self.featureQ = featureQ

    def run(self):
        P300fun(self.dataInQ, self.featureQ)

threadLock = threading.Lock()
SaveQ = queue.Queue()
DataOutQ1 = queue.Queue()
DataOutQ2 = queue.Queue()
FeatQ1 = queue.Queue()
FeatQ2 = queue.Queue()

#NEW:: initializes Events
E = threading.Event()
EP300 = threading.Event()
#
AcqTh = AcqThread(DataOutQ1, DataOutQ2, SaveQ)
P300Th = P300Thread(DataOutQ1, FeatQ1)
它允许我“反复”调用“线程B”,因为它在激活时保持我的第一个线程(由于事件E),并且仅在设置事件EP300时才进入处理部分。然后,在处理完成后清除EP300:

def Acquisition(inlet, dataOutQ1, dataOutQ2 saveQ):
    i = 0
    print('Starting...')
    while i<1250:
        sample, timestamp = inlet.pull_sample()
        ##Normalization, filtering##
        if _condition_:
            threadLock.acquire()
            dataOutQ1.put([filtsamples[:,-250:], rawtimestamps[-250:]])
            threadLock.release()
            EP300.set() #NEW:: allows the P300 function to collect data from queue
        i += 1
    E.set() #NEW:: flaggs end data collection

def P300fun(dataInQ, featureQ):
    p300sample = []
    p300timestamp = []
    while not E.is_set(): #NEW:: loop until collection is ended
        if EP300.is_set(): #NEW:: activated when Event is triggered
            while dataInQ.qsize():
                try:
                    print("DataInQ has data")
                    ss, ts = dataInQ.get(0) 
                    print('<>P300\n>>Samples [', ss, ']\nTimestamp [', ts, ']')
                except Empty:
                    return
        if not E.is_set(): #NEW:: Event is cleared in case data collection is not over, waiting for a new set()
            EP300.clear()
    print('Thread Finished')

if __name__ == '__main__':
    print('Looking for an EEG stream...')
    streams = resolve_stream('type', 'EEG')
    inlet = StreamInlet(streams[0])
    print('Connected!\n')

    AcqTh.start()
    P300Th.start()

    AcqTh.join()
    P300Th.join()

    print("\n\n>>>DONE<<<\n\n")
def采集(入口、dataOutQ1、dataOutQ2 saveQ): i=0 打印('开始…')
当我成为一个傻瓜可能会很棘手。。。因此,我将回答自己的问题,以帮助其他可能遇到此问题的初学者

首先:不,不可能从线程中重复调用线程,因为每个线程只能调用一次

但是有一种方法可以防止线程结束,让它们等待允许它们继续的触发器。经过更多的研究,我发现有一种方法可以为线程创建事件。可以找到文档。这非常简单:事件对象的行为类似于标志,可以是
set()
(表示True)或
clear()
(表示False,这是原始值)。要测试事件,可以使用
is_set()
方法解决布尔问题,或者使用
wait()
方法代替计时器。就我而言,它为我节省了一些我将要使用的队列:

import threading
import queue
from queue import Empty
import numpy as np


class AcqThread(threading.Thread):
    def __init__(self, dataOutQ1, dataOutQ2, saveQ):
        threading.Thread.__init__(self)
        self.dataOutQ2 = dataOutQ2
        self.dataOutQ1 = dataOutQ1
        self.saveQ = saveQ

    def run(self):
        Acquisition(inlet, self.dataOutQ1, self.dataOutQ2, self.saveQ)

class P300Thread(threading.Thread):
    def __init__(self, dataInQ, featureQ):
        threading.Thread.__init__(self)
        self.dataInQ = dataInQ
        self.featureQ = featureQ

    def run(self):
        P300fun(self.dataInQ, self.featureQ)

threadLock = threading.Lock()
SaveQ = queue.Queue()
DataOutQ1 = queue.Queue()
DataOutQ2 = queue.Queue()
FeatQ1 = queue.Queue()
FeatQ2 = queue.Queue()

#NEW:: initializes Events
E = threading.Event()
EP300 = threading.Event()
#
AcqTh = AcqThread(DataOutQ1, DataOutQ2, SaveQ)
P300Th = P300Thread(DataOutQ1, FeatQ1)
它允许我“反复”调用“线程B”,因为它在激活时保持我的第一个线程(由于事件E),并且仅在设置事件EP300时才进入处理部分。然后,在处理完成后清除EP300:

def Acquisition(inlet, dataOutQ1, dataOutQ2 saveQ):
    i = 0
    print('Starting...')
    while i<1250:
        sample, timestamp = inlet.pull_sample()
        ##Normalization, filtering##
        if _condition_:
            threadLock.acquire()
            dataOutQ1.put([filtsamples[:,-250:], rawtimestamps[-250:]])
            threadLock.release()
            EP300.set() #NEW:: allows the P300 function to collect data from queue
        i += 1
    E.set() #NEW:: flaggs end data collection

def P300fun(dataInQ, featureQ):
    p300sample = []
    p300timestamp = []
    while not E.is_set(): #NEW:: loop until collection is ended
        if EP300.is_set(): #NEW:: activated when Event is triggered
            while dataInQ.qsize():
                try:
                    print("DataInQ has data")
                    ss, ts = dataInQ.get(0) 
                    print('<>P300\n>>Samples [', ss, ']\nTimestamp [', ts, ']')
                except Empty:
                    return
        if not E.is_set(): #NEW:: Event is cleared in case data collection is not over, waiting for a new set()
            EP300.clear()
    print('Thread Finished')

if __name__ == '__main__':
    print('Looking for an EEG stream...')
    streams = resolve_stream('type', 'EEG')
    inlet = StreamInlet(streams[0])
    print('Connected!\n')

    AcqTh.start()
    P300Th.start()

    AcqTh.join()
    P300Th.join()

    print("\n\n>>>DONE<<<\n\n")
def采集(入口、dataOutQ1、dataOutQ2 saveQ): i=0 打印('开始…') 而我