user11141993
user11141993

Reputation:

Python : passing values between different processes

I have debugged my code for a while and I found out that bash_shell(message,shell) fails to pass the shell dictionary back to the main process. The dictionary is still blank but when I read (actually, print) shell in bash_shell(), it does have the value. Which means maybe because I passed the value of the variable but not the alias? But I saw other posts in other websites, people do it in that way and it works fine.

And I tried to do threading.Thread() instead of multiprocessing.Process(). The thread can pass the value back with global variables (didn't try the parameter method).

import multiprocessing,subprocess
# doing import stuff and blah blah blah
shell = dict()
shell['sh_out'] = ''
shell['py_out'] = ''
# code.... (in this part I also defined channel, guild, _globals, _locals,bot, etc...)
def bash_shell(msg,shell):
    global channel,guild,_globals,_locals
    try:
        proc = subprocess.Popen(msg.split(" "), stdout=subprocess.PIPE,text=True)
    except Exception as e:
        shell['sh_out'] = str(e) + '\n$'
        return
    (out, err) = proc.communicate()
    if err:
        shell['sh_out'] = '```\n' + str(out) + "\n```\nError: `" + str(err) + "`\n```\n$```"
    else:
        shell['sh_out'] = '```\n'+ str(out) + "\n$```"
    if len(rt) > 1988:
        f = open("samples/shoutput.txt","w")
        f.write(rt)
        f.close()
    return
#code.......
# @bot.event
def on_message(message):
    #again code......
    # if message.channel.name == 'bash':
        # p = multiprocessing.Process(target=bash_shell,args=[message,shell])
        p = multiprocessing.Process(target=bash_shell,args=['ls -al',shell])
        p.start()
        p.join(5)
        if p.is_alive():
            p.kill()
            shell['sh_out'] = "Enough fork bomb. Please don't try to hang the bot."
            p.join()
        if len(shell['sh_out']) > 1998:
            # await message.channel.send(file=discord.File(open("samples/shoutput.txt","r"),"output.txt"))
            shell['sh_out'] = ''
            return
        print(shell)
        # await message.channel.send(shell['sh_out'])
        shell['sh_out'] = ""
        return

on_message('a')

(note: if you wonder what I am doing, it's just a bot coded in discord.py. Code has been modified so that it is more understandable and easy to trigger the exception.)

So what did I do wrong? Or are there better ways to do the trick? Why can't it changes the dictionary shell but other people can do so?

Upvotes: 1

Views: 1735

Answers (1)

jossefaz
jossefaz

Reputation: 3932

You have two possibility:

1 ) Share Memory space between processes

2 ) Use the Manager Object provided by the multiprocessing library

But for the communication between process, you can use a Queue as mentionned in this excellent article :

https://www.geeksforgeeks.org/multiprocessing-python-set-2/amp/

Upvotes: 2

Related Questions