最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Python: Struggling with Multiprocessing - Stack Overflow

programmeradmin10浏览0评论

I'm currently working on a loudness meter with a raspberry pi and python. The raspberry is connected to a sensor for loudness metering and a common USB microphone. Whenever the value of the loudness meter exceeds a certain threshold, the microphone shall start a 10s recording, so that the source of the noise gets documented.

Everytime the microphone is recording something, the readout of values from the loudness meter should continue in parallel. Because of that, I thought of using the multiprocessing module. Unfortunately, this is new stuff for me and it's not working so far. Although every function is working on it's own, I haven't managed to make them work at the same time. Because of that, I would appreciate, if you could support me here.

In a short version, my code looks like this:

import multiprocessing

def reading_values_from_loudness_meter():
(...)
# This function checks the values continuously and appends them to a list, if they exceed the threshold.

def recording_audio():
(...)
# Checks, if there are values in the list and starts recording, when the list is not empty. Whenever a recording is triggered, the list gets cleared. Whenever the recording ends, the list is checked again for values.

u = 1
p1 = multiprocessing.Process(target=reading_values_from_loudness_meter)
p2 = multiprocessing.Process(target=recording_audio)

p1.start()
    
while u == 1:
    p2.start()
    p2.join()

I'm currently working on a loudness meter with a raspberry pi and python. The raspberry is connected to a sensor for loudness metering and a common USB microphone. Whenever the value of the loudness meter exceeds a certain threshold, the microphone shall start a 10s recording, so that the source of the noise gets documented.

Everytime the microphone is recording something, the readout of values from the loudness meter should continue in parallel. Because of that, I thought of using the multiprocessing module. Unfortunately, this is new stuff for me and it's not working so far. Although every function is working on it's own, I haven't managed to make them work at the same time. Because of that, I would appreciate, if you could support me here.

In a short version, my code looks like this:

import multiprocessing

def reading_values_from_loudness_meter():
(...)
# This function checks the values continuously and appends them to a list, if they exceed the threshold.

def recording_audio():
(...)
# Checks, if there are values in the list and starts recording, when the list is not empty. Whenever a recording is triggered, the list gets cleared. Whenever the recording ends, the list is checked again for values.

u = 1
p1 = multiprocessing.Process(target=reading_values_from_loudness_meter)
p2 = multiprocessing.Process(target=recording_audio)

p1.start()
    
while u == 1:
    p2.start()
    p2.join()
Share Improve this question edited Mar 19 at 23:31 mkrieger1 23.5k7 gold badges64 silver badges82 bronze badges asked Mar 19 at 22:39 FloFlo 91 bronze badge 5
  • You need to elaborate on it's not working so far. What happens? Are there errors, do you get no output? How have you verified that it doesn't work vs it doesn't look like its working but in reality it is? Multiprocessing can sometimes look as though it isn't working because you don't see some outputs in the terminal but that is just part of how each thread executes and where/how it returns output. – fam-woodpecker Commented Mar 19 at 22:44
  • Sorry for that...when I start the script, the values from the loudness meter are read until the threshold exceeds. Then, the audio recording starts, but the reading from the loudness meter stops. There is no reading and recording at the same time (no values in the terminal during recordings). But I'll check your hint again... – Flo Commented Mar 19 at 23:14
  • 2 Have you tried running them simultaneously from two independent terminals (i.e. not using multiprocessing but effectively doing so)? If they read and write from the same file, there may be some file locking going on so that only one process can access the file at a time – fam-woodpecker Commented Mar 19 at 23:26
  • It's likely that the two processes are not looking at the same data structure. You should probably include more (or all) of the code in the functions, or at least the code you use to communicate between the two. – Grismar Commented Mar 19 at 23:42
  • google/search?q=python+multiprocessing+share+variable – tevemadar Commented Mar 19 at 23:43
Add a comment  | 

1 Answer 1

Reset to default 1

There's a number of missing details from your example that might be part of why your script isn't working as you expected, but I'll start with the first that I noticed: You should not be start()ing a process more than once. It is not equivalent to calling a function over again.

Without having details on the listening and recording functions, it is difficult to tell any more about how your program works. I'll provide a basic framework below of how I would accomplish the task (not the only way.. There are many ways to do the same thing):

import multiprocessing

### for testing
import time
import random

def read_from_loudness_meter():
    time.sleep(.1)
    loudness = random.randint(0,100)
    print(f"\r{loudness}  ", end="")
    return loudness

def record_10_seconds():
    print("\nrecording start\n")
    time.sleep(10)
    print("\nrecording stop\n")
### for testing


def reading_values_from_loudness_meter(recording_lock, threshold):
    while True:
        loudness = read_from_loudness_meter()
        if loudness > threshold:
            # ensure lock is released
            try:
                recording_lock.release()
            except ValueError:
                #lock is already released
                pass


def recording_audio(recording_lock):
    while True:
        recording_lock.acquire()  # wait for the lock to be released
        record_10_seconds()  # record the audio here

        # Re-acquire the lock without waiting to ignore peaks that happened
        # during the recording. If you want to simply immediately start a new
        # recording if another peak was detected during the last recording,
        # simply remove this line
        recording_lock.acquire(block=False)


if __name__ == "__main__":  # This is not required on linux, but is a good
                            # habit in case you ever switch to Mac or Windows.

    threshold = 98
    recording_lock = multiprocessing.Lock()
    recording_lock.acquire()  # lock should start in the locked state

    p2 = multiprocessing.Process(target=recording_audio,
                                 args = (recording_lock,))
    p2.start()

    try:
        print("ctrl-c to stop")
        reading_values_from_loudness_meter(recording_lock, threshold)
    except KeyboardInterrupt:
        pass

    p2.terminate()
发布评论

评论列表(0)

  1. 暂无评论