Python Forum
Python Tkinter Simple Multithreading Question
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Python Tkinter Simple Multithreading Question
#1
I have a simple Listbox with a list of names that I would like to print concurrently, but also in the order of which they were added to the Listbox (alphabetically in this case). I'm just using this example to practice creating multiple threads to handle each name in the listbox.

So, just to clarify, I'd like to have 1 thread for each name in the list to print each name. I prefer to do this in the order they are in queue from whatever the listbox has in it.

Here's what I've tried thus far:

from tkinter import Tk, Button, Listbox import threading class MainWindow(Tk): def __init__(self): super().__init__() self.lb1 = Listbox(self, width=26, cursor='hand2') self.lb1.pack(side='left', fill='y', padx=20, pady=20) self.b1 = Button(self, text='START', bg='green', fg='white', cursor='hand2', command=self.start_thread) self.b1.pack(side='left') self.lb1.insert('end', 'Aaron') self.lb1.insert('end', 'Billy') self.lb1.insert('end', 'Chris') self.lb1.insert('end', 'David') self.lb1.insert('end', 'Edward') self.lb1.insert('end', 'Frank') self.lb1.insert('end', 'George') self.lb1.insert('end', 'Howard') self.lb1.insert('end', 'Ian') self.lb1.insert('end', 'Johnny') def start_thread(self): for i in range(self.lb1.size()): t1 = threading.Thread(target = self.work, args=(i,)) t1.start() def work(self, i): print(self.lb1.get(i)) if __name__ == '__main__': app = MainWindow() app.title('Main Window') app.configure(bg='#333333') app.mainloop()
The problem that I'm having is that the threads do not fire off properly. They print the names out in random order and also on the same exact line as if they are just one name at times. How do I get better control of each thread that will print each name concurrently?

Below is an example of what is being printed out:


ChrisEdward DavidBilly George Aaron Frank Ian JohnnyHoward
Reply
#2
If you want to control when they run, don't put each in their own thread? Unless the code something to synchronize execution of the threads, they just finish in whatever order they want. Normally you don't care.

As for them all printing on the same line, I am not seeing that, but it is probably just because stdout is not being flushed after each write
Reply
#3
There are multiple threads each trying to control the same resource, terminal output, so the results are unpredictable. I use multiprocessing and a Manager (common) list in the cases when I want to do something like this. But while memory is faster than printing, the order can not be guaranteed and so you would sort the list before printing.

from tkinter import Tk, Button, Listbox from functools import partial import multiprocessing as mp class MainWindow(): def __init__(self, mp_list): self.root=Tk() self.root.title('Main Window') self.root.configure(bg='#333333') self.lb1 = Listbox(self.root, width=26, cursor='hand2') self.lb1.pack(side='left', fill='y', padx=20, pady=20) self.b1 = Button(self.root, text='START', bg='green', fg='white', cursor='hand2', command=partial(self.start_thread, mp_list)) self.b1.pack(side='left') Button(self.root, text='QUIT', bg='orange', command=self.root.quit).pack(side="left") self.lb1.insert('end', 'Aaron') self.lb1.insert('end', 'Billy') self.lb1.insert('end', 'Chris') self.lb1.insert('end', 'David') self.lb1.insert('end', 'Edward') self.lb1.insert('end', 'Frank') self.lb1.insert('end', 'George') self.lb1.insert('end', 'Howard') self.lb1.insert('end', 'Ian') self.lb1.insert('end', 'Johnny') self.root.mainloop() def start_thread(self, mp_list): self.b1.config(state="disabled") self.process_list=[] for i in range(self.lb1.size()): t1 = mp.Process(target = self.work, args=(i, mp_list,)) t1.start() self.process_list.append(t1) def work(self, i, mp_list): mp_list.append(self.lb1.get(i)) if __name__ == '__main__': manager=mp.Manager() mp_list=manager.list() app = MainWindow(mp_list) print(mp_list) 
Reply
#4
C:\Users\Aaron\AppData\Local\Programs\Python\Python310\python.exe "C:/Users/Aaron/Documents/Python/EBSEO PRO/2.py" Exception in Tkinter callback Traceback (most recent call last): File "C:\Users\Aaron\AppData\Local\Programs\Python\Python310\lib\tkinter\__init__.py", line 1921, in __call__ return self.func(*args) File "C:\Users\Aaron\Documents\Python\EBSEO PRO\2.py", line 41, in start_thread t1.start() File "C:\Users\Aaron\AppData\Local\Programs\Python\Python310\lib\multiprocessing\process.py", line 121, in start self._popen = self._Popen(self) File "C:\Users\Aaron\AppData\Local\Programs\Python\Python310\lib\multiprocessing\context.py", line 224, in _Popen return _default_context.get_context().Process._Popen(process_obj) File "C:\Users\Aaron\AppData\Local\Programs\Python\Python310\lib\multiprocessing\context.py", line 336, in _Popen return Popen(process_obj) File "C:\Users\Aaron\AppData\Local\Programs\Python\Python310\lib\multiprocessing\popen_spawn_win32.py", line 93, in __init__ reduction.dump(process_obj, to_child) File "C:\Users\Aaron\AppData\Local\Programs\Python\Python310\lib\multiprocessing\reduction.py", line 60, in dump ForkingPickler(file, protocol).dump(obj) TypeError: cannot pickle '_tkinter.tkapp' object Traceback (most recent call last): File "<string>", line 1, in <module> File "C:\Users\Aaron\AppData\Local\Programs\Python\Python310\lib\multiprocessing\spawn.py", line 116, in spawn_main exitcode = _main(fd, parent_sentinel) File "C:\Users\Aaron\AppData\Local\Programs\Python\Python310\lib\multiprocessing\spawn.py", line 126, in _main self = reduction.pickle.load(from_parent) EOFError: Ran out of input
(Dec-14-2022, 08:03 PM)woooee Wrote: There are multiple threads each trying to control the same resource, terminal output, so the results are unpredictable. I use multiprocessing and a Manager (common) list in the cases when I want to do something like this. But while memory is faster than printing, the order can not be guaranteed and so you would sort the list before printing.

from tkinter import Tk, Button, Listbox from functools import partial import multiprocessing as mp class MainWindow(): def __init__(self, mp_list): self.root=Tk() self.root.title('Main Window') self.root.configure(bg='#333333') self.lb1 = Listbox(self.root, width=26, cursor='hand2') self.lb1.pack(side='left', fill='y', padx=20, pady=20) self.b1 = Button(self.root, text='START', bg='green', fg='white', cursor='hand2', command=partial(self.start_thread, mp_list)) self.b1.pack(side='left') Button(self.root, text='QUIT', bg='orange', command=self.root.quit).pack(side="left") self.lb1.insert('end', 'Aaron') self.lb1.insert('end', 'Billy') self.lb1.insert('end', 'Chris') self.lb1.insert('end', 'David') self.lb1.insert('end', 'Edward') self.lb1.insert('end', 'Frank') self.lb1.insert('end', 'George') self.lb1.insert('end', 'Howard') self.lb1.insert('end', 'Ian') self.lb1.insert('end', 'Johnny') self.root.mainloop() def start_thread(self, mp_list): self.b1.config(state="disabled") self.process_list=[] for i in range(self.lb1.size()): t1 = mp.Process(target = self.work, args=(i, mp_list,)) t1.start() self.process_list.append(t1) def work(self, i, mp_list): mp_list.append(self.lb1.get(i)) if __name__ == '__main__': manager=mp.Manager() mp_list=manager.list() app = MainWindow(mp_list) print(mp_list) 
Reply
#5
Ran fine on my Linux box. Don't have any idea what this means

EOFError: Ran out of input
Reply
#6
It is a pickling error. You don't get it running on linux because linux python doesn't pickle arguments passed to processes.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  multithreading xlwings error Equivocal 0 1,058 Jan-25-2025, 05:10 PM
Last Post: Equivocal
  Very Beginner question on simple variables Harvy 1 1,367 Apr-12-2024, 12:03 AM
Last Post: deanhystad
  Simple Question - ' defined as "a". ?' Ryan012 10 4,916 May-27-2023, 06:03 PM
Last Post: Ryan012
  Very simple question about filenames and backslashes! garynewport 4 7,078 Jan-17-2023, 05:02 AM
Last Post: deanhystad
  Tkinter Web Scraping w/Multithreading Question.... AaronCatolico1 3 3,256 Dec-16-2022, 11:34 AM
Last Post: deanhystad
  python Multithreading on single file mg24 3 4,328 Nov-05-2022, 01:33 PM
Last Post: snippsat
  multithreading Hanyx 4 2,764 Jul-29-2022, 07:28 AM
Last Post: Larz60+
  A simple "If...Else" question from a beginner Serena2022 6 4,118 Jul-11-2022, 05:59 AM
Last Post: Serena2022
Question Problems with variables in multithreading Wombaz 2 2,542 Mar-08-2022, 03:32 PM
Last Post: Wombaz
  Simple arithmetic question ebolisa 5 4,062 Dec-15-2021, 04:56 PM
Last Post: deanhystad

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020
This forum uses Lukasz Tkacz MyBB addons.
Forum use Krzysztof "Supryk" Supryczynski addons.