python队列是线程安全的吗_python – 为什么我的多进程队列看起来不是线程安全的?...

我正在构建一个运行另一个

Python程序的监视程序计时器,如果它无法从任何线程中找到签入,则关闭整个程序.这样,它最终将能够控制所需的通信端口.计时器的代码如下:

from multiprocessing import Process, Queue

from time import sleep

from copy import deepcopy

PATH_TO_FILE = r'.\test_program.py'

WATCHDOG_TIMEOUT = 2

class Watchdog:

def __init__(self, filepath, timeout):

self.filepath = filepath

self.timeout = timeout

self.threadIdQ = Queue()

self.knownThreads = {}

def start(self):

threadIdQ = self.threadIdQ

process = Process(target = self._executeFile)

process.start()

try:

while True:

unaccountedThreads = deepcopy(self.knownThreads)

# Empty queue since last wake. Add new thread IDs to knownThreads, and account for all known thread IDs

# in queue

while not threadIdQ.empty():

threadId = threadIdQ.get()

if threadId in self.knownThreads:

unaccountedThreads.pop(threadId, None)

else:

print('New threadId < {} > discovered'.format(threadId))

self.knownThreads[threadId] = False

# If there is a known thread that is unaccounted for, then it has either hung or crashed.

# Shut everything down.

if len(unaccountedThreads) > 0:

print('The following threads are unaccounted for:\n')

for threadId in unaccountedThreads:

print(threadId)

print('\nShutting down!!!')

break

else:

print('No unaccounted threads...')

sleep(self.timeout)

# Account for any exceptions thrown in the watchdog timer itself

except:

process.terminate()

raise

process.terminate()

def _executeFile(self):

with open(self.filepath, 'r') as f:

exec(f.read(), {'wdQueue' : self.threadIdQ})

if __name__ == '__main__':

wd = Watchdog(PATH_TO_FILE, WATCHDOG_TIMEOUT)

wd.start()

我还有一个小程序来测试看门狗功能

from time import sleep

from threading import Thread

from queue import SimpleQueue

Q_TO_Q_DELAY = 0.013

class QToQ:

def __init__(self, processQueue, threadQueue):

self.processQueue = processQueue

self.threadQueue = threadQueue

Thread(name='queueToQueue', target=self._run).start()

def _run(self):

pQ = self.processQueue

tQ = self.threadQueue

while True:

while not tQ.empty():

sleep(Q_TO_Q_DELAY)

pQ.put(tQ.get())

def fastThread(q):

while True:

print('Fast thread, checking in!')

q.put('fastID')

sleep(0.5)

def slowThread(q):

while True:

print('Slow thread, checking in...')

q.put('slowID')

sleep(1.5)

def hangThread(q):

print('Hanging thread, checked in')

q.put('hangID')

while True:

pass

print('Hello! I am a program that spawns threads!\n\n')

threadQ = SimpleQueue()

Thread(name='fastThread', target=fastThread, args=(threadQ,)).start()

Thread(name='slowThread', target=slowThread, args=(threadQ,)).start()

Thread(name='hangThread', target=hangThread, args=(threadQ,)).start()

QToQ(wdQueue, threadQ)

正如您所看到的,我需要将线程放入queue.Queue,而单独的对象会慢慢将queue.Queue的输出提供给多处理队列.相反,如果我将线程直接放入多处理队列中,或者在put之间没有QToQ对象休眠,则多处理队列将锁定,并且在看门狗端看起来总是为空.

现在,由于多处理队列应该是线程和进程安全的,我只能假设我在实现中搞砸了一些东西.我的解决方案似乎有效,但也觉得hacky足够我觉得我应该解决它.

我正在使用Python 3.7.2,如果重要的话.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值