Skip to content

Multiprocessing not compatible with Flet #4283

Description

@ap4499

Here is an example of the issue that I am finding with multiprocessing. The GUI effectively doubles when Multiprocessing is called. The reason for this is that Python's Multiprocessing calls sys.executable to obtain the Python interpreter to run the new processes/workers. (see comment)

When the Flet application is built, as discussed, sys.executable will by default point to the application executable. Hence, this behaviour will only be observed within applications that have been built using Flet Build, and not Flet Run.. further, PyInstaller seem to have fixed this - so it isn't present in Flet Pack.

Application:

  • Basic sort of the same list of numbers, but across multiple workers (processes).
  • Using a multiprocessing.Queue() to pass information.
  • Running the long running task using page.run_thread()
  • Updating the GUI only from the main thread.

Behaviour:

  • When running from terminal/ Flet Run the application behaves as expected.
  • When running the .app created with Flet Build (using your latest dev build from yday, dev3598), there are two behaviours:
  • As soon as the application is launched, another GUI window appears. I believe this is when we create the Multiprocessing.queue()
  • When the actual processing starts, a window is created for each worker that is used by multiprocessing.

#main.py

import flet as ft
from flet import Page, Text, ElevatedButton
from multiprocessing import Queue
import numpy as np
from concurrent.futures import ProcessPoolExecutor, as_completed


def sort_sublist(sublist):
    """Sorts a sublist of numbers."""
    return sorted(sublist)


def parallel_sort(queue_var):
    num_elements = 10_000_000  
    data = np.random.rand(num_elements).tolist()
    number_of_sorts = 20
    """Sorts a list of numbers in parallel."""

    with ProcessPoolExecutor(max_workers=10) as executor:
        futures = [executor.submit(sort_sublist, data) for _ in range(number_of_sorts)]  # Sort the same list x times
        for future in as_completed(futures):
            queue_var.put(1) 


def main(page: Page):
    page.title = "Flet Background Task Example"
    queue_var = Queue()
    text = ft.Text("Init")
    

    def update_text():
        completed = 0
        while True:
            completed += queue_var.get()
            text.value = completed
            text.update()

    def on_click(e):
        page.run_thread(parallel_sort,queue_var)
        update_text()


    page.add(
        ElevatedButton("Start Loop", on_click=on_click),
    )
    page.add(
        text
    )

if __name__ == "__main__":
    multiprocessing.freeze_support()
    ft.app(target=main)

#requirements.txt

flet==0.25.0.dev3598
numpy

Originally posted by @ap4499 in #4252 (comment)

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

Status
👀 In review

Relationships

None yet

Development

No branches or pull requests

Issue actions