Python Forum

Full Version: How to communicate between scripts in python via shared file?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi,
I have been watching videos and looking up a solution to this for the past day but still cant seem to wrap my mind around this. If there is another thread that explains this please point it out to me.

In simple words I want to have two .py files that have a particular aspect to them like this. So long as A is running, B will stop. And so long as B is running A will stop.

I am not going to go into great detail of what the actual situation is just to save you all the details. I have a mock up situation which closely resembles what I am actually dealing with with my esp32 and a sort of multifunction timer +.

The mock up situation looks like this. A count which continually prints out a count, '1.. 2.. 3.."
Then on the other hand there is a timer. Just a standard timer like would be used while cooking or for studying. However this program I also have printing out 'The clock is on..' just so I can see if what I am attempting to do has been succesfull yet. Which as mention above is that whenever the counter is on, the timer is off, vise versa.

After playing around with it for a while I turned to chatgpt for help so these mock-ups are actually written by it mostly and not me.

I am trying to do this through a shared file which each of the two individual programs will update their status to, "clock_status" and "numberator_status"

For instance:
'clock_status' is set to 1 within the clock program like this
"shared.clock_status == 1". Then it sets the corresponding numberator status to 0
like this,
"shared.numberator_status == 0"

If not clear the shared module is called shared.py


here is the script from chat gpt:

# shared.py
import threading


numberator_status = 1  # 1 means numberator is running, 0 means stopped
clock_status = 0  # 0 means clock is off, 1 means clock is running

lock = threading.Lock()


import time
import shared
import threading






#play_module.py

# Function to generate numbers
def number_generator():
    i = 0
    while True:
        with shared.lock:  # Lock to ensure thread safety
            if shared.numberator_status == 0:
                # Stop the generator if numberator_status is 0
                print("Numberator stopped.")
                return  # Exit the thread gracefully when stopped
            print(f"Generated number: {i}")
        i += 1
        time.sleep(2)  # Simulate number generation with a delay

# Function to start the numberator
def start_numberator():
    with shared.lock:
        shared.numberator_status = 1  # Set numberator to running
        print("Numberator started.")

# Run the number generator task in its own thread
def run_number_generator():
    start_numberator()
    number_generator_thread = threading.Thread(target=number_generator)
    number_generator_thread.start()

# Initially start the numberator if needed
run_number_generator()










#variable_clock.py

import time
import shared
import threading

# Clock function (simulated task)
def clock_task():
    while True:
        with shared.lock:  # Lock to ensure thread safety
            if shared.clock_status == 0:
                # Stop the clock if clock_status is 0
                print("Clock stopped.")
                return  # Exit the thread gracefully when stopped
            print("Clock is running...")
        time.sleep(1)

# Function to start the clock
def start_clock():
    with shared.lock:
        shared.clock_status = 1  # Set clock to running
        shared.numberator_status = 0  # Stop the numberator when clock starts
        print("Clock started.")
    
# Function to stop the clock
def stop_clock():
    with shared.lock:
        shared.clock_status = 0  # Set clock to stopped
        print("Clock stopped.")

# Run the clock task in its own thread
def run_clock():
    start_clock()
    clock_thread = threading.Thread(target=clock_task)
    clock_thread.start()

# Start the clock
run_clock()
I already tried a few different methods of having the two individual files update in to the shared.py file but for some reason it just doesnt seem to work. Is it the case that the only way to do this is to have them all in the same .py file? I dont think so, I just don't have experience to know.
It seems that you are confusing many things. There are files, processes and threads. Files don't communicate. Processes can communicate and threads can communicate too.

When you start a Python process by running a script, it may involve several files: the main program that you are calling and modules imported by this main program, which are defined in other files.

You can launch simultaneously several processes with the same python file. Each of these processes will be given a portion of live memory to store the variables that it defines and these memory spaces are separated and they don't communicate although the programs are written in the same files.

So the location of the code in one file or another has nothing to do with your problem.

(Dec-28-2024, 03:01 PM)daiboonchu Wrote: [ -> ]So long as A is running, B will stop. And so long as B is running A will stop.
In order to do this, you don't need two threads. A single thread suffices because the two tasks don't run concurently. You could do
# file main.py
from fileA import run_A
from fileB import run_B

def main():
    while True:
        run_A()
        run_B()

if __name__ == '__main__':
    main()
Or perhaps try to give a better description of the problem, forgetting completely the "files" question and concentrating on the tasks that the program must do and how it chooses to run one task or the other, or something else.
I agree with Griboullis, but thinking about the original problem/question. You want program A to stop then program B is running and vice versa? What would be the trigger to get one of the programs to stop? Once A is running B would never start, unless you are also having A and B stop in other circumstances.. Also, if using file as your means of communication you likely need to close the file and make sure it flushes in order to make any changes visible to the other program

Then again, my suggestion would be to use async and await.
You can use a shared file to communicate between Python scripts.

1. Script 1: Writing to the File
python
Copy code
# script1.py
with open("shared_file.txt", "w") as file:
file.write("Hello from script 1!")
2. Script 2: Reading from the File
python
Copy code
# script2.py
with open("shared_file.txt", "r") as file:
data = file.read()
print(f"Data from script 1: {data}")
3. How to Use It
First, run script1.py to write data into the file.
Then, run script2.py to read the data.
This is a simple way for scripts to share data using a text file. You can also use formats like JSON or CSV for more structured data.
For more detailed examples and to learn more about file handling, check out Link Removed which covers all the essentials and more advanced concepts!
As jefsummers said, something must stop A or B will never start. What stops A?

And what is the purpose of the status variables? Why do you need them?

Put your clock and your "numberator" (don't like that word) in one programme as functions.

I don't know what you really want to do. You have not been too clear. Maybe this will give you some ideas:

# So long as A is running, B will stop. And so long as B is running A will stop.
# If A starts first, what stops A so that B can start?

import sys
# make shared available
sys.path.append('enum/')

import shared

# at the start
print(f'shared.clock_status = {shared.clock_status}')
print(f'shared.number_status = {shared.number_status}')

def A():
    for a in range(5):
        if a%2 == 0:
            print('tick')
        else:
            print('tock')
    # change shared variables
    shared.clock_status = 0
    shared.number_status = 1
    print(f'shared.clock_status = {shared.clock_status}')
    print(f'shared.number_status = {shared.number_status}')

def B():
    for a in range(5):
        print(f'number = {a}')
    # revert shared variables to original values
    shared.clock_status = 1
    shared.number_status = 0
    print(f'shared.clock_status = {shared.clock_status}')
    print(f'shared.number_status = {shared.number_status}')

count = 0
while count < 5:
    A()
    B()
    count+= 1