3

I know that it is not possible to run multiple loops at the same time in Python. Anyhow, what I need to achieve is that I have one loop running reading loads of sensor data, every 0.25 seconds. At the same time I have signal devices running in parallel that need to send signals every 3 seconds. My question is what way is best practice to achieve this?

Does it make sense to write two scripts and run them in parallel? Does it make sense to use threading? Is there any other possibility in order to make this work?

I would be greatful for code samples.

Thank you!

Edit: Both loops are absolutely independent. So, let's say while script 1 is running, reading the sensor data, when one of the sensors received a value < 300, it should run script 2 which will send the signals. At the same time when the sensors data gets > 300 it should stop script 2.

5
  • You can do everything in one loop using a priority queue with actions ordered by time. In a loop, pop an item, wait until its time is due, execute its action, then schedule a new item 3s or .25s later. Commented Jan 10, 2014 at 13:19
  • How do you check for the time interval in those loops? Are those reads and sends blocking the loop? The simplest option would be trying to launch a send signal once every 12 read sensor data. Commented Jan 10, 2014 at 13:23
  • Look into Python threading - it's definitely possible to run multiple loops at the same time. Commented Jan 10, 2014 at 13:24
  • 1
    If the two tasks are completely unrelated, you probably should write two separate programs. Otherwise, @larsmans 's suggestion is probably the best choice if your tasks are lightweight (execute quickly). If your tasks are related and will take some time to execute (such that the execution of one task can take more time than the interval between tasks), you should probably use threads (or processes, depending if it's I/O bound or CPU bound) Commented Jan 10, 2014 at 13:24
  • @larmans: I've tried that, but in some way it interferes with the signal processing. As the signal processing uses several counters as well. Needs further investigation where the interference comes from. Commented Jan 10, 2014 at 21:30

2 Answers 2

6

"Python multiple loops at the same time. I know that it is not possible [...]" - this looks really funny.

It is possible to run two loops at the same time, exactly how you described it. And both ways make much sense, depending on what do you actually need and want. If the tasks are completely independent you should run it as two scripts. If you need those two loops to realize one task and it makes sense for them to be in one file you can use multiprocessing.

Tested for python 2.7.5+ and 3.3.2+.

Here is some minimal example:

from multiprocessing import Process
import time

def f(name):
    print('hello', name)
    time.sleep(10)

def d(name):
    print('test2', name)
    time.sleep(10)

if __name__ == '__main__':
    p1 = Process(target=f, args=('bob',))
    p2 = Process(target=d, args=('alice',))
    p1.start()
    p2.start()
    p1.join()
    p2.join()

Script runs for 10s and both strings are printed right away, which means everything works.

time python3 ./process.py 
hello bob
test2 alice

real  0m10.073s
user  0m0.040s
sys   0m0.016s
Sign up to request clarification or add additional context in comments.

5 Comments

Sorry for my bad English :) The loops are independent, please see the Edit on my question.
So how would the solution look like iff the tasks are completely independent and I'd like to run it as two scripts?
Put f() into f.py run it in the background, and put d() into d.py and run it in the background. From your description the scripts do not have to communicate just keep on running. There is nothing more. You have to look around how to run task in bg on your system, but it is separate independent problem.
I run this code on 2.7.10, if I keep running it for several times, the output is messed up. Is there any reason for that?
NOTICE: if I move the time.sleep() in front of the print(), and insert time.time() inside print(), the output could be messed up if I run it several times. Here is one of the messed up outputs: ('h('tesello't2', 'bob, '', alice', 1509462604.0133221509462604.013331)) . I run this code on 2.7.10. Could anyone explain why?
0

It is also possible by running multiple scripts and some as .pyw for convenience and having them exchange information by UDP sockets. Note 127.0.0.1 is to send to yourself under ANY circumstance. Also for port, just make sure no other programs use the port you use. As in other programs, I mean ANY program that uses ports or even basic router settings.

Sample (send)

import os
from sockets import *
host = "ip"
port = "9000"
addr = (host, port)
UDPSock = socket(AF_INET, SOCK_DGRAM)
data = "Random Text"
send = data.encode("ascii")
UDPSock.sendto(send, addr)
UDPSock.close()

Sample (Receive)

import os
from socket import *
host = ""
port = 9000
addr = (host, port)
UDPSock = socket(AF_INET, SOCK_DGRAM)
UDPSock.bind(addr)
(data, addr) = UDPSock.recvfrom(1024)#1024 is MAX bytes to receive
data = data.decode('ascii')
UDPSock.close()

You can use these to run separate loops and tell what to do from two separate programs.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.