Sorry for the lousy title, "InterProcess Communication" was too long
Basically, I'm looking to use the native
msvcrt modules to launch an integrated python interpreter and communicate with it over pipes
I can't find anything on Google or DDG, and I've been searching for days, but nobody uses these modules for some reason...
I already have the foundation with a 1-way Parent->Child pipe that works, but it's giving me a few issues:
1: I can't seem to get a 2nd Child->Parent pipe to run without the program hanging
2: the output of the subprocess only prints after the main process is closed (tbh though I rather want the main process to actively print through subprocess feedback, even if it's delayed a few ns)
Note that the code came from the CPU-heavy multiprocessing module.
(I just reduced the processing, so this code wastes MUCH less CPU cycles)
# -*- coding: utf-8 -*- from _winapi import CreatePipe, CreateProcess, CloseHandle from msvcrt import open_osfhandle import _winapi, msvcrt from nt import getpid # this is just a mock-up path to a local interpreter, since __file__ doesn't include the drive letter on wine CWD = 'Z:%s'%__file__.replace('test.py','').replace('\\','/') exec_path = '%sapp/'%CWD executable = '%spython.exe'%exec_path rhandle, whandle = CreatePipe(None, 0) # Parent to Child prog = ''' from _winapi import OpenProcess, DuplicateHandle, GetCurrentProcess, CloseHandle from _winapi import PROCESS_DUP_HANDLE, DUPLICATE_SAME_ACCESS, DUPLICATE_CLOSE_SOURCE from msvcrt import open_osfhandle import sys sys.path = ['.\\DLLs','%s'] # because -I doesn't "Isolate" as well as it's supposed to, and we still have environment paths here. source_process_handle = OpenProcess(PROCESS_DUP_HANDLE, False, %s) try: handle = DuplicateHandle( source_process_handle, %s, GetCurrentProcess(), 0, False, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE) from_parent = open( open_osfhandle( handle, 0 ), 'rb', closefd=True ) # not using `with` because I intend to open a 2nd pipe to write to exec(from_parent.read()) from_parent.close() sys.exit(0) finally: CloseHandle(source_process_handle)'''%(exec_path, getpid(), rhandle) cmd = '%s -I -S -c "%s" --multiprocessing-fork'%(executable, prog) to_child = open( open_osfhandle( whandle, 0 ), 'wb', closefd=True ) # not using `with` because I intend to open a 2nd pipe to read from # start process try: subprocess_handle, thread_handle, pid, tid = CreateProcess( executable, cmd, None, None, False, 0, None, None, None) CloseHandle(thread_handle) except: CloseHandle(rhandle) raise # send information to child to_child.write(b'print("success!")') for i in range(10000000): i+i+1 # give the subprocess enough time to complete input('Press Enter to Exit...\n\n') CloseHandle(subprocess_handle) to_child.close()
Is there any way I can introduce a 2nd pipe to have proper interprocess communication??
btw, to those looking to use this as an example, I highly recommend you NOT send raw python code through the pipe like I'm doing here with
What I'm doing is for testing purposes only, and should not be used in practical cases as it's extremely insecure!
multiprocessing module uses the
pickle module, but that's a joke because you can easily get the authstring to unpickle the pipe...
see this image:
so it's essentially just wasting a ton of CPU cycles to send code over the pipe.
also, fun fact
from the image, you can use
type(cp) to gain access to the deleted
class MainProcess(BaseProcess): class.
But to get back on topic, what you should do is define code in the subprocess that analyzes the input read from the pipe and interprets commands from it that are specific to your app with the supplied data.