0

I want to write a small alarm-clock-script in Python 3. I want to make it a CLI-tool with Click so I can pass an alarm time, a start command and a stop command. I don't need help with this itself.

The problem I struggle with is the fact, that when I run my script / commands, the terminal is not available for other commands. So I want to run the program in the background (or another thread?).

Example:

CLI-command 1: define alarm '12:00:00'
CLI-command 2: start alarm

After I set the alarm-time (with define alarm) and started the start-function (which constantly checks if the alarm time is reached) I want to do other stuff in the same terminal. At 12:00:00 the alarm should raise a sound.

As I said, the function works, but while it runs, I am not able to use the same terminal for other things. How can I manage to put this process (checking if the alarm.time is reached) into the background so that I am still be able to use the same terminal for other stuff?

I want to be os-independent (it should run on Windows, Linux and Mac).

Any advise what to read or look into?

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
FrankBlack78
  • 152
  • 11
  • 2
    Does this help https://stackoverflow.com/questions/2905965/creating-threads-in-python – Jo Bay May 26 '21 at 14:59
  • 3
    This is actually a bigger project than you think it is. Do you want the alarm process to continue running if the user closes the shell? If they log off? If they reboot? When the alarm goes off, what do you want to have happen? Just spit a message out into whatever they happen to be doing in the terminal? IMHO you are probably better off using the system's method of doing this even though it will be different on different platforms (cron on Linux/Mac OS X, Task Scheduler on Windows). – kindall May 26 '21 at 15:02
  • If you created a "tray" icon in `pystray` rather than using a CLI tool some of this becomes easier. If you follow @JoBay's suggestion (it is a good one), I recommend looking for an answer that uses `concurrent.futures` as I find it easier to work with. – JonSG May 26 '21 at 15:08
  • Dang. Should have know that this wasn't such an easy task. Thanks for the hints. I will read them tomorrow. BTW: The alarm-function just has to be present for the duration of the terminal-session (not after reboot or something like this). – FrankBlack78 May 26 '21 at 15:44

2 Answers2

1

If you want to run a task in the background you can create a process which does the task that you want and then make the system exit it. You can do this by:

import os
import sys
pid = os.fork()
if pid == 0:
        print("Running task")
        sys.exit()
        sleep(10000)
        print("Task ended")
else:
        print("Running another task")



drauedo
  • 641
  • 4
  • 17
  • I think that solves my problem. The sleep function in your example is not reachable. I changed the code a bit: `from time import sleep import os import sys pid = os.fork() if pid == 0: print("Running task") sleep(10) print("Task ended") sys.exit() else: sys.exit()` – FrankBlack78 May 27 '21 at 08:55
  • Is there a way to kill the process e. g. with another python function? In my use-case i want to start the alarm-timer with that. I want to be able to kill the timer (after I started it) with another command. And what, if there are multiple instances of the timer? How can I kill a specific one? – FrankBlack78 May 27 '21 at 10:49
1

If you want to achieve this without adding complexity to your code itself, you can just run using the screen command like so:

$ screen -d -m -S alarmclock python your_alarm_clock_script.py

The '-d -m' will start a detached session. The '-S' allows you to name that session.

You can then use:

$ screen -ls
$ screen -r

to view your sessions and resume the alarmclock session respectively.

This is OS independent so long as your OS has Bash installed.

Sam
  • 46
  • 1
  • 3