Running multiple commands simultaneously in python - multithreading

I'm making an application that plays multiple notes simultaneously.
I've tried multithreading and a lot of other libraries, but they all just play the sounds after oneanother.
This is what i've currently got:
import threading
import winsound
def playsound(notes, length):
for note in notes:
t = threading.Thread(target=winsound.Beep, args=(note,length))
t.start()
playsound([100,200,300],200)

Related

How to use Release and Acquire in Lock in python multithreading?

I was trying to implement a program that can simultaneously change the elements of an array and print it, using multithreading in python.
from threading import Thread
import threading
import random
def print_ele(array):
count=True
while count:
print(array)
def change_ele():
array=[1,2,3,4]
t1=Thread(target=print_ele,args=(array,))
t1.start()
lock=threading.Lock()
random.seed(10)
count=True
while count:
lock.acquire()
for i in range(5):
array[i]=random.random()
lock.release()
change_ele()
I expect to get different random numbers printed in each iteration. But instead it seems that the array gets updated only once.
I know that we can do the same thing without multithreading. But I was wondering if we could do the same thing using multithreading.

How to deal with python3 multiprocessing in __main__.py

Il posed question, I did not understand the ture cause of the issue (it seems to have been related to my usage of flask in one of the subprocesses).
PLEASE IGNORE THIS (can't delete due to bounty)
Essentially, I have to start some Processes and or a pool when running a python library as a module.
However, since __name__ == '__main__' is always true in __main__.py this proves to be an issue (see multiprocessing docs: https://docs.python.org/3/library/multiprocessing.html)
I've attempted multiple solutions ranging from: pytgquabr.com:8182/58288945/using-multiprocessing-with-runpy to a file-based mutext to only allow the contents of main to run once but multiprocessing still behaves strangely (e.g. Processes die almost as soon as they start with no error logs).
Any idea of what the "proper" way of going about this is ?
Guarding the __main__ module is only needed if an object defined inside __main__ is used in another process. Looking up this definition is what causes the execution of __main__ in the subprocess.
When using a __main__.py, restrict all definitions used with multiprocessing to other modules. __main__.py should only import and use these.
# my_package/some_module.py
def module_print(*args, **kwargs):
"""Function defined in some module - fine for use inside multiprocess"""
print(*args, **kwargs)
# my_package/__main__.py
import multiprocessing # imports are allowed
from .some_module import module_print
def do_multiprocess():
"""Function defined in __main__ module - fine for use wrapping multiprocess"""
with multiprocessing.Pool(processes=12) as pool:
pool.map(module_print, range(20)) # multiprocessing external function is allowed
do_multiprocess() # directly calling __main__ function is allowed

Python: How to store 2 sound files overlapped with each other [duplicate]

I have to make a player that can play two songs simultaneously.
The problem is that the only module that I could find that supports every sound manipulation method that I need to use is Pygame.mixer.music. Unfortunately it only supports a single music stream at once.
I tried to cheat the system using threads and multiprocessing but it didn't do the job.
My question is does anybody know a Python3 module that can play 2 songs at once and has the following possibilities: pause, stop, seek through the song, change volume and change speed of the song.
Or does anybody know how to do this with the Pygame module.
The multiprocessing code that I tried to use is down below if anybody can help with this I'd be grateful!
import pygame
import multiprocessing
pygame.mixer.init()
def play(arg):
pygame.mixer.init()
if arg:
print(arg)
pygame.mixer.music.load('song1.ogg')
pygame.mixer.music.play()
else:
print(arg)
pygame.mixer.music.load('song2.ogg')
pygame.mixer.music.play()
p1 = multiprocessing.Process(target=play, args=(True,))
p2 = multiprocessing.Process(target=play, args=(False,))
p1.start()
p2.start()
while True:
pass
You don't need any threading or multiprocessing. You can just paly 2 songs parallel using the pygame.mixer.Sound objects:
import pygame
pygame.mixer.init()
song_1 = pygame.mixer.Sound('song1.ogg')
song_2 = pygame.mixer.Sound('song2.ogg')
song_1.play(0)
song_2.play(0)
while pygame.mixer.get_busy():
pygame.time.delay(10)
I found a way to get the job done.
At the moment I am using 2 sound manipulation modules:
Pygame.mixer.music
python-vlc
They are working properly together and have the functions that I needed.

Why does some widgets don't update on Qt5?

I am trying to create a PyQt5 application, where I have used certain labels for displaying status variables. To update them, I have implemented custom pyqtSignal manually. However, on debugging I find that the value of GUI QLabel have changed but the values don't get reflected on the main window.
Some answers suggested calling QApplication().processEvents() occasionally. However, this instantaneously crashes the application and also freezes the application.
Here's a sample code (all required libraries are imported, it's just the part creating problem, the actual code is huge):
from multiprocessing import Process
def sub(signal):
i = 0
while (True):
if (i % 5 == 0):
signal.update(i)
class CustomSignal(QObject):
signal = pyqtSignal(int)
def update(value):
self.signal.emit(value)
class MainApp(QWidget):
def __init__(self):
super().__init__()
self.label = QLabel("0");
self.customSignal = CustomSignal()
self.subp = Process(target=sub, args=(customSignal,))
self.subp.start()
self.customSignal.signal.connect(self.updateValue)
def updateValue(self, value):
print("old value", self.label.text())
self.label.setText(str(value))
print("new value", self.label.text())
The output of the print statements is as expected. However, the text in label does not change.
The update function in CustomSignal is called by some thread.
I've applied the same method to update progress bar which works fine.
Is there any other fix for this, other than processEvents()?
The OS is Ubuntu 16.04.
The key problem lies in the very concept behind the code.
Processes have their own address space, and don't share data with another processes, unless some inter-process communication algorithm is used. Perhaps, multithreading module was used instead of threading module to bring concurrency to avoid Python's GIL and speedup the program. However, subprocess has cannot access the data of parent process.
I have tested two solutions to this case, and they seem to work.
threading module: No matter threading in Python is inefficient due to GIL, but it's still sufficient to some extent for basic concurrency demands. Note the difference between concurrency and speedup.
QThread: Since you are using PyQt, there's isn't any issue in using QThread, which is a better option because it takes concurrency to multiple cores taking advantage of operating system's system call, rather than Python in the middle.
Try adding
self.label.repaint()
immediately after updating the text, like this:
self.label.setText(str(value))
self.label.repaint()

wxPython manipulate GUI in same program

I am trying to create a GUI with wxPython. After I create the GUI I want the code to continue to execute, so I have tried to throw the app.MainLoop() onto a new thread. This gives me issues. Also when I try to change the background color for example, it freezes up the GUI.
import wx
import threading
from threading import Thread
from multiprocessing import Process
class Display(wx.Frame):
def __init__(self, *args, **kwargs):
print 'here'
self.app = wx.App(False)
super(Display, self).__init__(*args, **kwargs)
self.SetTitle("Yo mama")
self.Show(True)
thread = Thread(target = self.app.MainLoop)
thread.start()
self.Close()
def DisplayGUI(self):
self.SetTitle("MyTitle")
self.Show(True)
def Changetitle(self):
self.SetTitle("Title2")
display = Display(None)
# do stuff
display.ChangeTitle()
# do stuff
So basically I want to be able to run a GUI, and control it later on within my program (not through the GUI itself with events). I plan on having pictures display at random times.
The GUI's MainLoop needs to run in the main thread. So do this, and if you want events at random times, you can use a timer, for example, wx.Timer.
Using this approach, all the changes you mention (displaying pictures, changing the titles, colors, etc) should be straightforward. Plus, you'll get a lot more control this way, where you can start and stop timers, change the interval, have multiple timers, setup timers that trigger each other, and many other options.
To learn more about wx.Timer, a good place to start is always the demo. There's also a tutorial here, and a video here.
(I've heard that there are ways to run the MainLoop in a separate thread, but nothing you mention requires that, and it will be much, much easier to just use a timer.)

Resources