Hele
Hele

Reputation: 395

multiprocessing help: launching Loops

What I have:
Web application that does some things, running on Bottle microframework, here is the Main

def run_server():
    bottle.run(host=env.str('SRVRIP'), port=env.str('SRVRPORT'), debug=False)

    # Main
    if __name__ == '__main__':
        run_server()



What I want to add:
I want to split this app in 2 processes: first called main_service() which simply runs the server, second called backup_service() which has to take a periodic Db backup (once per hour)



What I've tried
First I've tried with the asyncio module, failing miserably (tried just for fun and to understand something new). Now I'm facing on multiprocessing (leaving aside threading cause I don't want GIL troubles), but I can't understand how to make it work, here is my code:

import multiprocessing
import time
import os


def main_service():
    print(f'Process {os.getpid()}')

    while(True):
        sentence=input()
        print(f'USER: {sentence}')


def backup_service():
    print(f'Process {os.getpgid()}')

    while(True):
        print('BACKUP')
        time.sleep(1)


if __name__ == "__main__":
    processes = []

    t = multiprocessing.Process(target=main_service())
    processes.append(t)
    t.start()

    t = multiprocessing.Process(target=backup_service())
    processes.append(t)
    t.start()

    for process in processes:
        process.join()

    print('Done')

If run

Process 14608
As you can see
USER: As you can see
It asks for input
USER: It asks for input
But backup_service() is not printing anything
USER: But backup_service() is not printing anything

Expected output

Process 14608
While I'm writing
USER: While I'm writing
BACKUP
every second
USER: every second
backup_service() has to print 'BACKUP' USER: backup_service() has to print 'BACKUP' BACKUP

Can anyone help?

Upvotes: 0

Views: 49

Answers (2)

Gabriele
Gabriele

Reputation: 302

You split your app in 2 processes but then you don't know what to do in the main process: why don't you simply run only one new process (for the backup) and you keep the web server loop running in the main process that started your program?

Something like this should work (not tested):

import multiprocessing
import time
import os

def backup_service():
    print(f'Process {os.getpgid()}')

    while(True):
        print('BACKUP')
        time.sleep(1)


if __name__ == "__main__":
    t = multiprocessing.Process(target=backup_service)
    t.daemon = True
    t.start()
    bottle.run(host=env.str('SRVRIP'), port=env.str('SRVRPORT'), debug=False)

keep it simple...

Upvotes: 1

John
John

Reputation: 2127

process.join() is never getting to the second process because process.join() only ends when the process that it's joining terminates. In your case, the process is an infinite loop so it never terminates and it never advances the loop to the next process.

You could get around this and see some output from the other process by using the timeout option for join(). Alternatively, you could have your processes output to different files and tail those files to confirm that they're both running.

Upvotes: 1

Related Questions