dsanson / termpdf.py

A graphical pdf and epub reader that works inside the kitty terminal
MIT License
496 stars 30 forks source link

Threading #13

Open dsanson opened 4 years ago

dsanson commented 4 years ago

Features that I'd like to implement that require multiple threads:

jaeheum commented 3 years ago

view thread busy loops with 100% cpu usage on linux, each instance of termpdf pegging a core completely. I don't have a mac to test if the same problem happens there.

$ sudo py-spy dump --pid 171809
...
Python v3.9.1 (/usr/bin/python3.9)

Thread 171809 (idle)
    _shutdown (threading.py:1428)
Thread 171813 (idle)
    watch_for_file_change (termpdf.py:1490)
    run (threading.py:892)
    _bootstrap_inner (threading.py:954)
    _bootstrap (threading.py:912)
Thread 171814 (active)
    view (termpdf.py:1530)
    run (threading.py:892)
    _bootstrap_inner (threading.py:954)
    _bootstrap (threading.py:912)
$ sudo py-spy top --pid 171809
...
GIL: 3.00%, Active: 104.00%, Threads: 3

  %Own   %Total  OwnTime  TotalTime  Function (filename:line)                   
 97.00%  97.00%   11.70s    11.70s   view (termpdf.py:1530)
  4.00%   4.00%   0.380s    0.380s   _shutdown (threading.py:1428)
  3.00%   3.00%   0.170s    0.300s   view (termpdf.py:1529)
  0.00%   0.00%   0.130s    0.130s   is_set (threading.py:531)
  0.00%   0.00%   0.050s    0.050s   watch_for_file_change (termpdf.py:1490)
  0.00% 100.00%   0.000s    12.05s   _bootstrap (threading.py:912)
  0.00% 100.00%   0.000s    12.05s   run (threading.py:892)
  0.00% 100.00%   0.000s    12.05s   _bootstrap_inner (threading.py:954)

It is possible to make the busy loop by removing scr.stdscr.nodelay(True) but that breaks the file_change detection or autorefresh. I have settled on a very small change of waiting on file_change in the loop of view (termpdf.py:1530)

while key == -1 and not file_change.isSet():                             
    file_change.wait(0.5)                                                
    key = scr.stdscr.getch()                                             

With this change I see cpu usage of a few percent at most, the thread running view idle, not active.

$ sudo py-spy dump --pid 171656
...
Python v3.9.1 (/usr/bin/python3.9)

Thread 171656 (idle)
    _shutdown (threading.py:1428)
Thread 171658 (idle)
    watch_for_file_change (termpdf.py:1490)
    run (threading.py:892)
    _bootstrap_inner (threading.py:954)
    _bootstrap (threading.py:912)
Thread 171659 (idle)
    wait (threading.py:316)
    wait (threading.py:574)
    view (termpdf.py:1530)
    run (threading.py:892)
    _bootstrap_inner (threading.py:954)
    _bootstrap (threading.py:912)

A few notes: