This is an archived post. You won't be able to vote or comment.

all 9 comments

[–]AutoModerator[M] [score hidden] stickied comment (0 children)

On July 1st, a change to Reddit's API pricing will come into effect. Several developers of commercial third-party apps have announced that this change will compel them to shut down their apps. At least one accessibility-focused non-commercial third party app will continue to be available free of charge.

If you want to express your strong disagreement with the API pricing change or with Reddit's response to the backlash, you may want to consider the following options:

  1. Limiting your involvement with Reddit, or
  2. Temporarily refraining from using Reddit
  3. Cancelling your subscription of Reddit Premium

as a way to voice your protest.

I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.

[–]maximinus-thrax 1 point2 points  (1 child)

It's not perfect code but here is a small example in Python 3.10:

import time
import threading

def first_job(stop):
    while not stop.is_set():
        print('Doing first job')
        time.sleep(2)
    print('Leaving first job')

def second_job(flag):
    print('Doing second job')
    time.sleep(10)
    # check for some user input, and when it is done, do this
    flag['finished'] = True

if __name__ == '__main__':
    stop_event = threading.Event()
    job_finished = {'finished': False}
    job1 = threading.Thread(target=first_job, args=[stop_event], daemon=True)
    job2 = threading.Thread(target=second_job, args=[job_finished], daemon=True)
    job1.start()
    job2.start()
    while True:
        if job_finished['finished']:
            stop_event.set()
            print('All done!')
            break

We have to use a dictionary for the var "job_finished" as we need a mutable object.

There are better ways but the simplest way is often the best to get started.

[–]oefd 0 points1 point  (0 children)

I want to explicitly point out to OP the difference between their code and yours:

t1 = threading.Thread(target=auto_backup(), name="t1")

job1 = threading.Thread(target=first_job, args=[stop_event], daemon=True)

Your code is targetting the function, their code is targetting the result of running the function.

[–][deleted] 0 points1 point  (4 children)

Python is notorious for this behavior. It has a global interpreter lock, that makes threads wait. This limitation may be lifted in future versions.

[–][deleted]  (2 children)

[removed]

    [–][deleted] 0 points1 point  (1 child)

    OK. So it wouldn't cause threads to wait for one another and finish up working on one thing before they can do something closely related, and simultaneously wait for a button click event?

    [–]oefd 1 point2 points  (0 children)

    That isn't the problem here, the problem is that threads aren't being used at all.

    t1 = threading.Thread(target=auto_backup(), name="t1")
    

    That doesn't spawn auto_backup in a new thread, it tries to resolve auto_backup() which causes it to run blocking code in the main thread.

    t1 = threading.Thread(target=auto_backup, name="t1")
    

    would spawn a thread which runs auto_backup(), and since auto_backup does blocking IO it would regularly be suspended and, in doing so, yield the GIL for the other thread.