多个Python线程写入单个JSON文件
我正在调整中的Python脚本(如下展开),以更新JSON文件的元素,而不是初始状态拖缆。但是,对于由脚本打开的多个线程,不可能将每个线程中的数据简洁地写回文件,因为它将在所有线程中同时被读取、更改和写回文件。因为只能有一个文件,所以没有一个版本是准确的,因为最后一个线程将覆盖所有其他文件 问题:如何(同时)更新每个线程中基于JSON的状态,而不影响其他线程的写入操作或锁定文件? JSON文件包含我想用python脚本处理的占用者状态: 这是python脚本: 我想我们都同意,最好的办法是将每个线程的数据返回到main,并将其写入一个位置的文件中,但这是令人困惑的地方,因为每个线程都检查不同的人,如何将状态传递回main进行写入多个Python线程写入单个JSON文件,python,json,multithreading,Python,Json,Multithreading,我正在调整中的Python脚本(如下展开),以更新JSON文件的元素,而不是初始状态拖缆。但是,对于由脚本打开的多个线程,不可能将每个线程中的数据简洁地写回文件,因为它将在所有线程中同时被读取、更改和写回文件。因为只能有一个文件,所以没有一个版本是准确的,因为最后一个线程将覆盖所有其他文件 问题:如何(同时)更新每个线程中基于JSON的状态,而不影响其他线程的写入操作或锁定文件? JSON文件包含我想用python脚本处理的占用者状态: 这是python脚本: 我想我们都同意,最好的办法是将每个
{
"janeHome": "false",
"johnHome": "false",
"jennyHome": "false",
"jamesHome": "false"
}
import subprocess
import json
from time import sleep
from threading import Thread
# Edit these for how many people/devices you want to track
occupant = ["Jane","John","Jenny","James"]
# MAC addresses for our phones
address = ["11:22:33:44:55:66","77:88:99:00:11:22","33:44:55:66:77:88","99:00:11:22:33:44"]
# Sleep once right when this script is called to give the Pi enough time
# to connect to the network
sleep(60)
# Some arrays to help minimize streaming and account for devices
# disappearing from the network when asleep
firstRun = [1] * len(occupant)
presentSent = [0] * len(occupant)
notPresentSent = [0] * len(occupant)
counter = [0] * len(occupant)
# Function that checks for device presence
def whosHere(i):
# 30 second pause to allow main thread to finish arp-scan and populate output
sleep(30)
# Loop through checking for devices and counting if they're not present
while True:
# Exits thread if Keyboard Interrupt occurs
if stop == True:
print ("Exiting Thread")
exit()
else:
pass
# If a listed device address is present print
if address[i] in output:
print(occupant[i] + "'s device is connected")
if presentSent[i] == 0:
# TODO: UPDATE THIS OCCUPANT'S STATUS TO TRUE
# Reset counters so another stream isn't sent if the device
# is still present
firstRun[i] = 0
presentSent[i] = 1
notPresentSent[i] = 0
counter[i] = 0
sleep(900)
else:
# If a stream's already been sent, just wait for 15 minutes
counter[i] = 0
sleep(900)
# If a listed device address is not present, print and stream
else:
print(occupant[i] + "'s device is not connected")
# Only consider a device offline if it's counter has reached 30
# This is the same as 15 minutes passing
if counter[i] == 30 or firstRun[i] == 1:
firstRun[i] = 0
if notPresentSent[i] == 0:
# TODO: UPDATE THIS OCCUPANT'S STATUS TO FALSE
# Reset counters so another stream isn't sent if the device
# is still present
notPresentSent[i] = 1
presentSent[i] = 0
counter[i] = 0
else:
# If a stream's already been sent, wait 30 seconds
counter[i] = 0
sleep(30)
# Count how many 30 second intervals have happened since the device
# disappeared from the network
else:
counter[i] = counter[i] + 1
print(occupant[i] + "'s counter at " + str(counter[i]))
sleep(30)
# Main thread
try:
# Initialize a variable to trigger threads to exit when True
global stop
stop = False
# Start the thread(s)
# It will start as many threads as there are values in the occupant array
for i in range(len(occupant)):
t = Thread(target=whosHere, args=(i,))
t.start()
while True:
# Make output global so the threads can see it
global output
# Reads existing JSON file into buffer
with open("data.json", "r") as jsonFile:
data = json.load(jsonFile)
jsonFile.close()
# Assign list of devices on the network to "output"
output = subprocess.check_output("arp-scan -interface en1 --localnet -l", shell=True)
temp = data["janeHome"]
data["janeHome"] = # RETURNED STATE
data["johnHome"] = # RETURNED STATE
data["jennyHome"] = # RETURNED STATE
data["jamesHome"] = # RETURNED STATE
with open("data.json", "w") as jsonFile:
json.dump(data, jsonFile)
jsonFile.close()
# Wait 30 seconds between scans
sleep(30)
except KeyboardInterrupt:
# On a keyboard interrupt signal threads to exit
stop = True
exit()