examples icon indicating copy to clipboard operation
examples copied to clipboard

help multiprocess

Open orcim-wind opened this issue 3 years ago • 2 comments

Hi, can you help me in this example: when i add a row with button [Add] the method 'appLine' adds a line correctly while the external process consumer using the same 'Appline' method fails thanks a lot


# flet
import flet
from flet import (
	Container, Page, Row, Column, animation, transform,
	VerticalDivider, Text, colors,
	ListView, FilledButton, UserControl
)

# multiprocess
from multiprocessing import Process
from multiprocessing import Queue
# from multiprocessing import Value
from queue import Empty

from time import sleep
from random import random

#---------------------------------------------------------
# myClass
#---------------------------------------------------------
class MyApp(UserControl):

	#-------------------------------------------------------
	# override the constructor
	def __init__(self, que):
		# execute the base constructor
		UserControl.__init__(self)

		#-----------------------------------------------------
		# ListView
		self.lVie=ListView(
			expand=1, 
			auto_scroll=True,
		)

		self.lCou = 1
		self.fCol = "#00bb00"
		self.bCol = '#000000'
		self.que  = que
		self.prd  = None

	#-------------------------------------------------------
	def appLine(self, item):

		if item:
			self.lVie.controls.append(
				Text(
					# f"Line {self.lCou}",
					f">{item}",
					color=self.fCol,
					bgcolor=self.bCol,
				)
			)
			self.lCou += 1
			try:
				self.update()
			except:
				...

	#-------------------------------------------------------
	def build(self):

		#-----------------------------------------------------
		# Button
		self.btn1 = FilledButton(
			text=" Add ",
			# expand=1,
			on_click=self.clicked_btn,
			data="btn1",
		)
		self.btn2 = FilledButton(
			text=" Rem ",
			# expand=1,
			on_click=self.clicked_btn,
			data="btn2",
		)

		#-----------------------------------------------------
		# Container
		return Container(

			Row(
				[

					# Left
					Container(
						bgcolor=colors.SURFACE_VARIANT,
						width=150,
						height=700,
						border_radius=10,
					),

					VerticalDivider(),

					# Middle
					Container(
						bgcolor=self.bCol,
						width=150,
						height=700,
						# border_radius=10,
						expand=1, 
						content=Row(
							controls=[
								self.lVie,
							],
						),
					),

					VerticalDivider(),
					
					# Right
					Container(
						bgcolor=colors.SURFACE_VARIANT,
						width=150,
						height=700,
						# expand=True,
						border_radius=10,
						padding=20,
						content=Column(
								controls=[
										Column(
												controls=[
													self.btn1,
													self.btn2,
												],
										),
								],
						),
					),

				],
				spacing=0,
				expand=True,
			),
		)
		
	#-------------------------------------------------------
	# Button
	def clicked_btn(self, e):
		# print("data:", e.control.data)

		if e.control.data == 'btn1':
			# print("Btn1")
			self.appLine(f"Line {self.lCou}")

			# start generate work
			self.prd = prodStart(self)
			self.prd.start()

		elif e.control.data == 'btn2':
			# print("Btn2")
			if self.lVie.controls.__len__():
				# self.lVie.controls.pop()
				self.lVie.controls.__delitem__(0)
				# self.lCou -= 1
			self.update()

#---------------------------------------------------------
# Application
#---------------------------------------------------------
def main(page: Page):

	page.title = "myApp"
	page.add(app)

#---------------------------------------------------------
# generate work
def producerT(self):
	print('Producer: Running', flush=True)
	# generate work
	for i in range(3):
		# generate a value
		value = random()
		# block
		sleep(value)
		# add to the queue
		self.que.put(value)
	print('Producer: Done', flush=True)

#---------------------------------------------------------
# instance work
def prodStart(self):
	# start the producer
	prod = Process(target=producerT, args=(self,))
	return prod

#-------------------------------------------------------
# consume work 
def consumer(self):
	print('Consumer: Running', flush=True)
	# consume work
	while True:
		# get a unit of work
		try:
			item = self.que.get(timeout=0.5)
		except Empty:
			# print('Consumer: waiting...', flush=True)
			continue
		# check for stop
		if item is None:
			# self.prd.terminate()
			print('Producer: Terminated', flush=True)
			break
		if item:
			# report
			print(f'<< {item}', flush=True)
			self.appLine(f'<< {item}')
	# all done
	print('Consumer: Terminated', flush=True)

#---------------------------------------------------------
# Main
#---------------------------------------------------------
# entry point
if __name__ == '__main__':

	# create the shared queue
	queue = Queue()

	app = MyApp(queue)
	app.horizontal_alignment="center",

	# start the consumer
	consumer_process = Process(target=consumer, args=(app,))
	consumer_process.start()
	# start the producer
	# producer_process = Process(target=producer, args=(queue,0))
	# producer_process.start()
	
	# Main loop
	flet.app(target=main)
	# flet.app(target=main, view=flet.WEB_BROWSER)

	# force stop consumer
	queue.put(None)

	# wait for all processes to finish
	# producer_process.join()
	consumer_process.join()

orcim-wind avatar Sep 03 '22 09:09 orcim-wind

What error are you getting? What OS is that, Python version, etc.? Could you give more context please?

FeodorFitsner avatar Sep 06 '22 20:09 FeodorFitsner

Linux 5.4.0-124-generic #140-Ubuntu SMP Python 3.8.10 If you run the script above and you set 2 breaks in the lines 57,49 You will be able to see, after pressing the Add button, that the "self.lVie" list is not correctly updated

orcim-wind avatar Sep 07 '22 06:09 orcim-wind