Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.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线程写入单个JSON文件_Python_Json_Multithreading - Fatal编程技术网

多个Python线程写入单个JSON文件

多个Python线程写入单个JSON文件,python,json,multithreading,Python,Json,Multithreading,我正在调整中的Python脚本(如下展开),以更新JSON文件的元素,而不是初始状态拖缆。但是,对于由脚本打开的多个线程,不可能将每个线程中的数据简洁地写回文件,因为它将在所有线程中同时被读取、更改和写回文件。因为只能有一个文件,所以没有一个版本是准确的,因为最后一个线程将覆盖所有其他文件 问题:如何(同时)更新每个线程中基于JSON的状态,而不影响其他线程的写入操作或锁定文件? JSON文件包含我想用python脚本处理的占用者状态: 这是python脚本: 我想我们都同意,最好的办法是将每个

我正在调整中的Python脚本(如下展开),以更新JSON文件的元素,而不是初始状态拖缆。但是,对于由脚本打开的多个线程,不可能将每个线程中的数据简洁地写回文件,因为它将在所有线程中同时被读取、更改和写回文件。因为只能有一个文件,所以没有一个版本是准确的,因为最后一个线程将覆盖所有其他文件

问题:如何(同时)更新每个线程中基于JSON的状态,而不影响其他线程的写入操作或锁定文件?

JSON文件包含我想用python脚本处理的占用者状态:

这是python脚本:

我想我们都同意,最好的办法是将每个线程的数据返回到main,并将其写入一个位置的文件中,但这是令人困惑的地方,因为每个线程都检查不同的人,如何将状态传递回main进行写入

{
 "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()