Send a signal/event to an independent process










0















So I have a completely independent process, with a known PID.



I want to send it some kind of interrupt from another unrelated process that will cause it to 'gracefully' exit.



In linux it would look something like this :



first_script:



def signal_handler(signum, stack):
print("SIGNAL RECIEVED")
sys.exit()

signal.signal(signal.SIGUSR1, handle_signal)
while True:
print("Im working")


Second script:



known_pid = input("Enter pid")
os.kill(int(known_pid), signal.SIGUSR1)


Since, Windows doesn't support signaling in this way, it obviously won't work but I couldn't find any other simple solution (After quite extensive research).










share|improve this question
























  • Does the process have a window that can be sent WM_CLOSE? Most GUI apps will exit gracefully (including asking to save files) if the main window is closed. This is what taskkill.exe does by default without the /F option. This can also be used for a console process if it's the effective owner of the console window (usually if it allocated the console). When the console window is closed, all applications attached to it (not just the owner) have no more than 5 seconds to handle the control event and exit gracefully before getting terminated.

    – eryksun
    Nov 13 '18 at 18:14











  • @eryksun It isnt a windows application(no GUI), and it isnt the owner of the console (otherwise I could use some varation of ctrl+c signals).

    – Rohi
    Nov 14 '18 at 7:02











  • Even if it were a console app, sending Ctrl+C is not simple in Windows. You have to be attached to the console (e.g. AttachConsole, FreeConsole). GenerateConsoleCtrlEvent works only with process groups, not arbitrary process IDs. If you know the group ID (i.e. the PID of the lead process), then you probably created the process with CREATE_NEW_PROCESS_GROUP, which disables Ctrl+C by default, so you have to use Ctrl+Break instead. Otherwise without a known group, you have to send to group 0 (all attached processes) and ignore the event in your own process.

    – eryksun
    Nov 14 '18 at 12:18











  • If it has no window or console, your last hope is that it's hosting a service (or services) that you can stop. Otherwise there's no standard way to signal a process. Windows has capabilities for this such as asynchronous procedure calls (APCs), named pipes, mailslots, events, and semaphores, but they're not a generic mechanism. An application has to be designed with a documented way to receive the signal.

    – eryksun
    Nov 14 '18 at 12:28











  • @Rohi does any of the answers have what you need? If not, what is missing? If you found a solution by yourself, please post it as an answer.

    – roeen30
    Nov 17 '18 at 17:53















0















So I have a completely independent process, with a known PID.



I want to send it some kind of interrupt from another unrelated process that will cause it to 'gracefully' exit.



In linux it would look something like this :



first_script:



def signal_handler(signum, stack):
print("SIGNAL RECIEVED")
sys.exit()

signal.signal(signal.SIGUSR1, handle_signal)
while True:
print("Im working")


Second script:



known_pid = input("Enter pid")
os.kill(int(known_pid), signal.SIGUSR1)


Since, Windows doesn't support signaling in this way, it obviously won't work but I couldn't find any other simple solution (After quite extensive research).










share|improve this question
























  • Does the process have a window that can be sent WM_CLOSE? Most GUI apps will exit gracefully (including asking to save files) if the main window is closed. This is what taskkill.exe does by default without the /F option. This can also be used for a console process if it's the effective owner of the console window (usually if it allocated the console). When the console window is closed, all applications attached to it (not just the owner) have no more than 5 seconds to handle the control event and exit gracefully before getting terminated.

    – eryksun
    Nov 13 '18 at 18:14











  • @eryksun It isnt a windows application(no GUI), and it isnt the owner of the console (otherwise I could use some varation of ctrl+c signals).

    – Rohi
    Nov 14 '18 at 7:02











  • Even if it were a console app, sending Ctrl+C is not simple in Windows. You have to be attached to the console (e.g. AttachConsole, FreeConsole). GenerateConsoleCtrlEvent works only with process groups, not arbitrary process IDs. If you know the group ID (i.e. the PID of the lead process), then you probably created the process with CREATE_NEW_PROCESS_GROUP, which disables Ctrl+C by default, so you have to use Ctrl+Break instead. Otherwise without a known group, you have to send to group 0 (all attached processes) and ignore the event in your own process.

    – eryksun
    Nov 14 '18 at 12:18











  • If it has no window or console, your last hope is that it's hosting a service (or services) that you can stop. Otherwise there's no standard way to signal a process. Windows has capabilities for this such as asynchronous procedure calls (APCs), named pipes, mailslots, events, and semaphores, but they're not a generic mechanism. An application has to be designed with a documented way to receive the signal.

    – eryksun
    Nov 14 '18 at 12:28











  • @Rohi does any of the answers have what you need? If not, what is missing? If you found a solution by yourself, please post it as an answer.

    – roeen30
    Nov 17 '18 at 17:53













0












0








0








So I have a completely independent process, with a known PID.



I want to send it some kind of interrupt from another unrelated process that will cause it to 'gracefully' exit.



In linux it would look something like this :



first_script:



def signal_handler(signum, stack):
print("SIGNAL RECIEVED")
sys.exit()

signal.signal(signal.SIGUSR1, handle_signal)
while True:
print("Im working")


Second script:



known_pid = input("Enter pid")
os.kill(int(known_pid), signal.SIGUSR1)


Since, Windows doesn't support signaling in this way, it obviously won't work but I couldn't find any other simple solution (After quite extensive research).










share|improve this question
















So I have a completely independent process, with a known PID.



I want to send it some kind of interrupt from another unrelated process that will cause it to 'gracefully' exit.



In linux it would look something like this :



first_script:



def signal_handler(signum, stack):
print("SIGNAL RECIEVED")
sys.exit()

signal.signal(signal.SIGUSR1, handle_signal)
while True:
print("Im working")


Second script:



known_pid = input("Enter pid")
os.kill(int(known_pid), signal.SIGUSR1)


Since, Windows doesn't support signaling in this way, it obviously won't work but I couldn't find any other simple solution (After quite extensive research).







python python-3.x windows






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 15:30







Rohi

















asked Nov 13 '18 at 14:05









RohiRohi

6321321




6321321












  • Does the process have a window that can be sent WM_CLOSE? Most GUI apps will exit gracefully (including asking to save files) if the main window is closed. This is what taskkill.exe does by default without the /F option. This can also be used for a console process if it's the effective owner of the console window (usually if it allocated the console). When the console window is closed, all applications attached to it (not just the owner) have no more than 5 seconds to handle the control event and exit gracefully before getting terminated.

    – eryksun
    Nov 13 '18 at 18:14











  • @eryksun It isnt a windows application(no GUI), and it isnt the owner of the console (otherwise I could use some varation of ctrl+c signals).

    – Rohi
    Nov 14 '18 at 7:02











  • Even if it were a console app, sending Ctrl+C is not simple in Windows. You have to be attached to the console (e.g. AttachConsole, FreeConsole). GenerateConsoleCtrlEvent works only with process groups, not arbitrary process IDs. If you know the group ID (i.e. the PID of the lead process), then you probably created the process with CREATE_NEW_PROCESS_GROUP, which disables Ctrl+C by default, so you have to use Ctrl+Break instead. Otherwise without a known group, you have to send to group 0 (all attached processes) and ignore the event in your own process.

    – eryksun
    Nov 14 '18 at 12:18











  • If it has no window or console, your last hope is that it's hosting a service (or services) that you can stop. Otherwise there's no standard way to signal a process. Windows has capabilities for this such as asynchronous procedure calls (APCs), named pipes, mailslots, events, and semaphores, but they're not a generic mechanism. An application has to be designed with a documented way to receive the signal.

    – eryksun
    Nov 14 '18 at 12:28











  • @Rohi does any of the answers have what you need? If not, what is missing? If you found a solution by yourself, please post it as an answer.

    – roeen30
    Nov 17 '18 at 17:53

















  • Does the process have a window that can be sent WM_CLOSE? Most GUI apps will exit gracefully (including asking to save files) if the main window is closed. This is what taskkill.exe does by default without the /F option. This can also be used for a console process if it's the effective owner of the console window (usually if it allocated the console). When the console window is closed, all applications attached to it (not just the owner) have no more than 5 seconds to handle the control event and exit gracefully before getting terminated.

    – eryksun
    Nov 13 '18 at 18:14











  • @eryksun It isnt a windows application(no GUI), and it isnt the owner of the console (otherwise I could use some varation of ctrl+c signals).

    – Rohi
    Nov 14 '18 at 7:02











  • Even if it were a console app, sending Ctrl+C is not simple in Windows. You have to be attached to the console (e.g. AttachConsole, FreeConsole). GenerateConsoleCtrlEvent works only with process groups, not arbitrary process IDs. If you know the group ID (i.e. the PID of the lead process), then you probably created the process with CREATE_NEW_PROCESS_GROUP, which disables Ctrl+C by default, so you have to use Ctrl+Break instead. Otherwise without a known group, you have to send to group 0 (all attached processes) and ignore the event in your own process.

    – eryksun
    Nov 14 '18 at 12:18











  • If it has no window or console, your last hope is that it's hosting a service (or services) that you can stop. Otherwise there's no standard way to signal a process. Windows has capabilities for this such as asynchronous procedure calls (APCs), named pipes, mailslots, events, and semaphores, but they're not a generic mechanism. An application has to be designed with a documented way to receive the signal.

    – eryksun
    Nov 14 '18 at 12:28











  • @Rohi does any of the answers have what you need? If not, what is missing? If you found a solution by yourself, please post it as an answer.

    – roeen30
    Nov 17 '18 at 17:53
















Does the process have a window that can be sent WM_CLOSE? Most GUI apps will exit gracefully (including asking to save files) if the main window is closed. This is what taskkill.exe does by default without the /F option. This can also be used for a console process if it's the effective owner of the console window (usually if it allocated the console). When the console window is closed, all applications attached to it (not just the owner) have no more than 5 seconds to handle the control event and exit gracefully before getting terminated.

– eryksun
Nov 13 '18 at 18:14





Does the process have a window that can be sent WM_CLOSE? Most GUI apps will exit gracefully (including asking to save files) if the main window is closed. This is what taskkill.exe does by default without the /F option. This can also be used for a console process if it's the effective owner of the console window (usually if it allocated the console). When the console window is closed, all applications attached to it (not just the owner) have no more than 5 seconds to handle the control event and exit gracefully before getting terminated.

– eryksun
Nov 13 '18 at 18:14













@eryksun It isnt a windows application(no GUI), and it isnt the owner of the console (otherwise I could use some varation of ctrl+c signals).

– Rohi
Nov 14 '18 at 7:02





@eryksun It isnt a windows application(no GUI), and it isnt the owner of the console (otherwise I could use some varation of ctrl+c signals).

– Rohi
Nov 14 '18 at 7:02













Even if it were a console app, sending Ctrl+C is not simple in Windows. You have to be attached to the console (e.g. AttachConsole, FreeConsole). GenerateConsoleCtrlEvent works only with process groups, not arbitrary process IDs. If you know the group ID (i.e. the PID of the lead process), then you probably created the process with CREATE_NEW_PROCESS_GROUP, which disables Ctrl+C by default, so you have to use Ctrl+Break instead. Otherwise without a known group, you have to send to group 0 (all attached processes) and ignore the event in your own process.

– eryksun
Nov 14 '18 at 12:18





Even if it were a console app, sending Ctrl+C is not simple in Windows. You have to be attached to the console (e.g. AttachConsole, FreeConsole). GenerateConsoleCtrlEvent works only with process groups, not arbitrary process IDs. If you know the group ID (i.e. the PID of the lead process), then you probably created the process with CREATE_NEW_PROCESS_GROUP, which disables Ctrl+C by default, so you have to use Ctrl+Break instead. Otherwise without a known group, you have to send to group 0 (all attached processes) and ignore the event in your own process.

– eryksun
Nov 14 '18 at 12:18













If it has no window or console, your last hope is that it's hosting a service (or services) that you can stop. Otherwise there's no standard way to signal a process. Windows has capabilities for this such as asynchronous procedure calls (APCs), named pipes, mailslots, events, and semaphores, but they're not a generic mechanism. An application has to be designed with a documented way to receive the signal.

– eryksun
Nov 14 '18 at 12:28





If it has no window or console, your last hope is that it's hosting a service (or services) that you can stop. Otherwise there's no standard way to signal a process. Windows has capabilities for this such as asynchronous procedure calls (APCs), named pipes, mailslots, events, and semaphores, but they're not a generic mechanism. An application has to be designed with a documented way to receive the signal.

– eryksun
Nov 14 '18 at 12:28













@Rohi does any of the answers have what you need? If not, what is missing? If you found a solution by yourself, please post it as an answer.

– roeen30
Nov 17 '18 at 17:53





@Rohi does any of the answers have what you need? If not, what is missing? If you found a solution by yourself, please post it as an answer.

– roeen30
Nov 17 '18 at 17:53












2 Answers
2






active

oldest

votes


















1





+50









You can use the Windows API as provided by pywin32 or hack it with a socket.



The socket solution is quick and dirty:



# waiting process

import socket
import select
import time

server = socket.socket()
server.bind(('localhost', 1337))
server.listen(5)

# this select() call returns ([server], , )
# if server is readable, else (, , ), and waits 0 seconds
while not select.select([server], , , 0)[0]:
print('working')
time.sleep(0.5)


# parent process

import socket
socket.create_connection(('localhost', 1337))


The windows solution is longer but more accurately represents the problem:



# waiting process

import time
import win32event

# open an existing event by name with the required access
# (didn't work for me with EVENT_MODIFY_STATE, got "Access denied" error)
event = win32event.OpenEvent(win32event.EVENT_ALL_ACCESS, 0, "MY_NAME")

# Wait 0 seconds on the event. If event has been set, WAIT_OBJECT_0 is returned
while win32event.WaitForSingleObject(event, 0) != win32event.WAIT_OBJECT_0:
print('working')
time.sleep(0.5)


# parent process
# note that it should be run first

import win32event
import time

# create event by name
event = win32event.CreateEvent(
None, # not inherited by child processes
False, # auto-reset the event after it is set
False, # created unset
"MY_NAME", # event name
)
time.sleep(5) # wait for waiting process to start
win32event.SetEvent(event)


This is only a minimal POC. It is recommended that you read about event objects to find the exact solution that suits you.






share|improve this answer




















  • 1





    The event-based approach is the right one (with sockets you can have painful timeouts). You can call CreateEvent with the same parameters on both sides (so you don't have to run one process before the other), just make sure you handle the ERROR_ALREADY_EXISTS error code. In this case EVENT_MODIFY_STATE | SYNCHRONIZE should be ok instead of EVENT_ALL_ACCESS

    – Simon Mourier
    Nov 17 '18 at 9:08












  • Hey, this looks like it could solve my problem. Ill have a thorough look at it tomrrow.

    – Rohi
    Nov 17 '18 at 18:53











  • Works exactly as I wanted, thanks!

    – Rohi
    Nov 18 '18 at 7:30











  • You dont actually have to open the event before the proccess check it, you can try catch on the proccess, making this a really good solution.

    – Rohi
    Nov 18 '18 at 9:44


















1














How about consider using psutil, I think it is quite suitable for your case.



As stated in document, following code can do what you want. Though you may not need the part of find_procs_by_name.



import os
import signal
import psutil

def find_procs_by_name(name):
"Return a list of processes matching 'name'."
ls =
for p in psutil.process_iter(attrs=["name", "exe", "cmdline"]):
if name == p.info['name'] or
p.info['exe'] and os.path.basename(p.info['exe']) == name or
p.info['cmdline'] and p.info['cmdline'][0] == name:
ls.append(p)
return ls

def kill_proc_tree(pid, sig=signal.SIGTERM, include_parent=True,
timeout=None, on_terminate=None):
"""Kill a process tree (including grandchildren) with signal
"sig" and return a (gone, still_alive) tuple.
"on_terminate", if specified, is a callabck function which is
called as soon as a child terminates.
"""
if pid == os.getpid():
raise RuntimeError("I refuse to kill myself")
parent = psutil.Process(pid)
children = parent.children(recursive=True)
if include_parent:
children.append(parent)
for p in children:
p.send_signal(sig)
gone, alive = psutil.wait_procs(children, timeout=timeout,
callback=on_terminate)
return (gone, alive)

pid = find_procs_by_name('POWERPNT.EXE')[0].pid
print(find_procs_by_name('POWERPNT.EXE')[0].pid)
kill_proc_tree(pid)





share|improve this answer






















    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53282800%2fsend-a-signal-event-to-an-independent-process%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1





    +50









    You can use the Windows API as provided by pywin32 or hack it with a socket.



    The socket solution is quick and dirty:



    # waiting process

    import socket
    import select
    import time

    server = socket.socket()
    server.bind(('localhost', 1337))
    server.listen(5)

    # this select() call returns ([server], , )
    # if server is readable, else (, , ), and waits 0 seconds
    while not select.select([server], , , 0)[0]:
    print('working')
    time.sleep(0.5)


    # parent process

    import socket
    socket.create_connection(('localhost', 1337))


    The windows solution is longer but more accurately represents the problem:



    # waiting process

    import time
    import win32event

    # open an existing event by name with the required access
    # (didn't work for me with EVENT_MODIFY_STATE, got "Access denied" error)
    event = win32event.OpenEvent(win32event.EVENT_ALL_ACCESS, 0, "MY_NAME")

    # Wait 0 seconds on the event. If event has been set, WAIT_OBJECT_0 is returned
    while win32event.WaitForSingleObject(event, 0) != win32event.WAIT_OBJECT_0:
    print('working')
    time.sleep(0.5)


    # parent process
    # note that it should be run first

    import win32event
    import time

    # create event by name
    event = win32event.CreateEvent(
    None, # not inherited by child processes
    False, # auto-reset the event after it is set
    False, # created unset
    "MY_NAME", # event name
    )
    time.sleep(5) # wait for waiting process to start
    win32event.SetEvent(event)


    This is only a minimal POC. It is recommended that you read about event objects to find the exact solution that suits you.






    share|improve this answer




















    • 1





      The event-based approach is the right one (with sockets you can have painful timeouts). You can call CreateEvent with the same parameters on both sides (so you don't have to run one process before the other), just make sure you handle the ERROR_ALREADY_EXISTS error code. In this case EVENT_MODIFY_STATE | SYNCHRONIZE should be ok instead of EVENT_ALL_ACCESS

      – Simon Mourier
      Nov 17 '18 at 9:08












    • Hey, this looks like it could solve my problem. Ill have a thorough look at it tomrrow.

      – Rohi
      Nov 17 '18 at 18:53











    • Works exactly as I wanted, thanks!

      – Rohi
      Nov 18 '18 at 7:30











    • You dont actually have to open the event before the proccess check it, you can try catch on the proccess, making this a really good solution.

      – Rohi
      Nov 18 '18 at 9:44















    1





    +50









    You can use the Windows API as provided by pywin32 or hack it with a socket.



    The socket solution is quick and dirty:



    # waiting process

    import socket
    import select
    import time

    server = socket.socket()
    server.bind(('localhost', 1337))
    server.listen(5)

    # this select() call returns ([server], , )
    # if server is readable, else (, , ), and waits 0 seconds
    while not select.select([server], , , 0)[0]:
    print('working')
    time.sleep(0.5)


    # parent process

    import socket
    socket.create_connection(('localhost', 1337))


    The windows solution is longer but more accurately represents the problem:



    # waiting process

    import time
    import win32event

    # open an existing event by name with the required access
    # (didn't work for me with EVENT_MODIFY_STATE, got "Access denied" error)
    event = win32event.OpenEvent(win32event.EVENT_ALL_ACCESS, 0, "MY_NAME")

    # Wait 0 seconds on the event. If event has been set, WAIT_OBJECT_0 is returned
    while win32event.WaitForSingleObject(event, 0) != win32event.WAIT_OBJECT_0:
    print('working')
    time.sleep(0.5)


    # parent process
    # note that it should be run first

    import win32event
    import time

    # create event by name
    event = win32event.CreateEvent(
    None, # not inherited by child processes
    False, # auto-reset the event after it is set
    False, # created unset
    "MY_NAME", # event name
    )
    time.sleep(5) # wait for waiting process to start
    win32event.SetEvent(event)


    This is only a minimal POC. It is recommended that you read about event objects to find the exact solution that suits you.






    share|improve this answer




















    • 1





      The event-based approach is the right one (with sockets you can have painful timeouts). You can call CreateEvent with the same parameters on both sides (so you don't have to run one process before the other), just make sure you handle the ERROR_ALREADY_EXISTS error code. In this case EVENT_MODIFY_STATE | SYNCHRONIZE should be ok instead of EVENT_ALL_ACCESS

      – Simon Mourier
      Nov 17 '18 at 9:08












    • Hey, this looks like it could solve my problem. Ill have a thorough look at it tomrrow.

      – Rohi
      Nov 17 '18 at 18:53











    • Works exactly as I wanted, thanks!

      – Rohi
      Nov 18 '18 at 7:30











    • You dont actually have to open the event before the proccess check it, you can try catch on the proccess, making this a really good solution.

      – Rohi
      Nov 18 '18 at 9:44













    1





    +50







    1





    +50



    1




    +50





    You can use the Windows API as provided by pywin32 or hack it with a socket.



    The socket solution is quick and dirty:



    # waiting process

    import socket
    import select
    import time

    server = socket.socket()
    server.bind(('localhost', 1337))
    server.listen(5)

    # this select() call returns ([server], , )
    # if server is readable, else (, , ), and waits 0 seconds
    while not select.select([server], , , 0)[0]:
    print('working')
    time.sleep(0.5)


    # parent process

    import socket
    socket.create_connection(('localhost', 1337))


    The windows solution is longer but more accurately represents the problem:



    # waiting process

    import time
    import win32event

    # open an existing event by name with the required access
    # (didn't work for me with EVENT_MODIFY_STATE, got "Access denied" error)
    event = win32event.OpenEvent(win32event.EVENT_ALL_ACCESS, 0, "MY_NAME")

    # Wait 0 seconds on the event. If event has been set, WAIT_OBJECT_0 is returned
    while win32event.WaitForSingleObject(event, 0) != win32event.WAIT_OBJECT_0:
    print('working')
    time.sleep(0.5)


    # parent process
    # note that it should be run first

    import win32event
    import time

    # create event by name
    event = win32event.CreateEvent(
    None, # not inherited by child processes
    False, # auto-reset the event after it is set
    False, # created unset
    "MY_NAME", # event name
    )
    time.sleep(5) # wait for waiting process to start
    win32event.SetEvent(event)


    This is only a minimal POC. It is recommended that you read about event objects to find the exact solution that suits you.






    share|improve this answer















    You can use the Windows API as provided by pywin32 or hack it with a socket.



    The socket solution is quick and dirty:



    # waiting process

    import socket
    import select
    import time

    server = socket.socket()
    server.bind(('localhost', 1337))
    server.listen(5)

    # this select() call returns ([server], , )
    # if server is readable, else (, , ), and waits 0 seconds
    while not select.select([server], , , 0)[0]:
    print('working')
    time.sleep(0.5)


    # parent process

    import socket
    socket.create_connection(('localhost', 1337))


    The windows solution is longer but more accurately represents the problem:



    # waiting process

    import time
    import win32event

    # open an existing event by name with the required access
    # (didn't work for me with EVENT_MODIFY_STATE, got "Access denied" error)
    event = win32event.OpenEvent(win32event.EVENT_ALL_ACCESS, 0, "MY_NAME")

    # Wait 0 seconds on the event. If event has been set, WAIT_OBJECT_0 is returned
    while win32event.WaitForSingleObject(event, 0) != win32event.WAIT_OBJECT_0:
    print('working')
    time.sleep(0.5)


    # parent process
    # note that it should be run first

    import win32event
    import time

    # create event by name
    event = win32event.CreateEvent(
    None, # not inherited by child processes
    False, # auto-reset the event after it is set
    False, # created unset
    "MY_NAME", # event name
    )
    time.sleep(5) # wait for waiting process to start
    win32event.SetEvent(event)


    This is only a minimal POC. It is recommended that you read about event objects to find the exact solution that suits you.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 16 '18 at 23:05

























    answered Nov 16 '18 at 22:51









    roeen30roeen30

    44629




    44629







    • 1





      The event-based approach is the right one (with sockets you can have painful timeouts). You can call CreateEvent with the same parameters on both sides (so you don't have to run one process before the other), just make sure you handle the ERROR_ALREADY_EXISTS error code. In this case EVENT_MODIFY_STATE | SYNCHRONIZE should be ok instead of EVENT_ALL_ACCESS

      – Simon Mourier
      Nov 17 '18 at 9:08












    • Hey, this looks like it could solve my problem. Ill have a thorough look at it tomrrow.

      – Rohi
      Nov 17 '18 at 18:53











    • Works exactly as I wanted, thanks!

      – Rohi
      Nov 18 '18 at 7:30











    • You dont actually have to open the event before the proccess check it, you can try catch on the proccess, making this a really good solution.

      – Rohi
      Nov 18 '18 at 9:44












    • 1





      The event-based approach is the right one (with sockets you can have painful timeouts). You can call CreateEvent with the same parameters on both sides (so you don't have to run one process before the other), just make sure you handle the ERROR_ALREADY_EXISTS error code. In this case EVENT_MODIFY_STATE | SYNCHRONIZE should be ok instead of EVENT_ALL_ACCESS

      – Simon Mourier
      Nov 17 '18 at 9:08












    • Hey, this looks like it could solve my problem. Ill have a thorough look at it tomrrow.

      – Rohi
      Nov 17 '18 at 18:53











    • Works exactly as I wanted, thanks!

      – Rohi
      Nov 18 '18 at 7:30











    • You dont actually have to open the event before the proccess check it, you can try catch on the proccess, making this a really good solution.

      – Rohi
      Nov 18 '18 at 9:44







    1




    1





    The event-based approach is the right one (with sockets you can have painful timeouts). You can call CreateEvent with the same parameters on both sides (so you don't have to run one process before the other), just make sure you handle the ERROR_ALREADY_EXISTS error code. In this case EVENT_MODIFY_STATE | SYNCHRONIZE should be ok instead of EVENT_ALL_ACCESS

    – Simon Mourier
    Nov 17 '18 at 9:08






    The event-based approach is the right one (with sockets you can have painful timeouts). You can call CreateEvent with the same parameters on both sides (so you don't have to run one process before the other), just make sure you handle the ERROR_ALREADY_EXISTS error code. In this case EVENT_MODIFY_STATE | SYNCHRONIZE should be ok instead of EVENT_ALL_ACCESS

    – Simon Mourier
    Nov 17 '18 at 9:08














    Hey, this looks like it could solve my problem. Ill have a thorough look at it tomrrow.

    – Rohi
    Nov 17 '18 at 18:53





    Hey, this looks like it could solve my problem. Ill have a thorough look at it tomrrow.

    – Rohi
    Nov 17 '18 at 18:53













    Works exactly as I wanted, thanks!

    – Rohi
    Nov 18 '18 at 7:30





    Works exactly as I wanted, thanks!

    – Rohi
    Nov 18 '18 at 7:30













    You dont actually have to open the event before the proccess check it, you can try catch on the proccess, making this a really good solution.

    – Rohi
    Nov 18 '18 at 9:44





    You dont actually have to open the event before the proccess check it, you can try catch on the proccess, making this a really good solution.

    – Rohi
    Nov 18 '18 at 9:44













    1














    How about consider using psutil, I think it is quite suitable for your case.



    As stated in document, following code can do what you want. Though you may not need the part of find_procs_by_name.



    import os
    import signal
    import psutil

    def find_procs_by_name(name):
    "Return a list of processes matching 'name'."
    ls =
    for p in psutil.process_iter(attrs=["name", "exe", "cmdline"]):
    if name == p.info['name'] or
    p.info['exe'] and os.path.basename(p.info['exe']) == name or
    p.info['cmdline'] and p.info['cmdline'][0] == name:
    ls.append(p)
    return ls

    def kill_proc_tree(pid, sig=signal.SIGTERM, include_parent=True,
    timeout=None, on_terminate=None):
    """Kill a process tree (including grandchildren) with signal
    "sig" and return a (gone, still_alive) tuple.
    "on_terminate", if specified, is a callabck function which is
    called as soon as a child terminates.
    """
    if pid == os.getpid():
    raise RuntimeError("I refuse to kill myself")
    parent = psutil.Process(pid)
    children = parent.children(recursive=True)
    if include_parent:
    children.append(parent)
    for p in children:
    p.send_signal(sig)
    gone, alive = psutil.wait_procs(children, timeout=timeout,
    callback=on_terminate)
    return (gone, alive)

    pid = find_procs_by_name('POWERPNT.EXE')[0].pid
    print(find_procs_by_name('POWERPNT.EXE')[0].pid)
    kill_proc_tree(pid)





    share|improve this answer



























      1














      How about consider using psutil, I think it is quite suitable for your case.



      As stated in document, following code can do what you want. Though you may not need the part of find_procs_by_name.



      import os
      import signal
      import psutil

      def find_procs_by_name(name):
      "Return a list of processes matching 'name'."
      ls =
      for p in psutil.process_iter(attrs=["name", "exe", "cmdline"]):
      if name == p.info['name'] or
      p.info['exe'] and os.path.basename(p.info['exe']) == name or
      p.info['cmdline'] and p.info['cmdline'][0] == name:
      ls.append(p)
      return ls

      def kill_proc_tree(pid, sig=signal.SIGTERM, include_parent=True,
      timeout=None, on_terminate=None):
      """Kill a process tree (including grandchildren) with signal
      "sig" and return a (gone, still_alive) tuple.
      "on_terminate", if specified, is a callabck function which is
      called as soon as a child terminates.
      """
      if pid == os.getpid():
      raise RuntimeError("I refuse to kill myself")
      parent = psutil.Process(pid)
      children = parent.children(recursive=True)
      if include_parent:
      children.append(parent)
      for p in children:
      p.send_signal(sig)
      gone, alive = psutil.wait_procs(children, timeout=timeout,
      callback=on_terminate)
      return (gone, alive)

      pid = find_procs_by_name('POWERPNT.EXE')[0].pid
      print(find_procs_by_name('POWERPNT.EXE')[0].pid)
      kill_proc_tree(pid)





      share|improve this answer

























        1












        1








        1







        How about consider using psutil, I think it is quite suitable for your case.



        As stated in document, following code can do what you want. Though you may not need the part of find_procs_by_name.



        import os
        import signal
        import psutil

        def find_procs_by_name(name):
        "Return a list of processes matching 'name'."
        ls =
        for p in psutil.process_iter(attrs=["name", "exe", "cmdline"]):
        if name == p.info['name'] or
        p.info['exe'] and os.path.basename(p.info['exe']) == name or
        p.info['cmdline'] and p.info['cmdline'][0] == name:
        ls.append(p)
        return ls

        def kill_proc_tree(pid, sig=signal.SIGTERM, include_parent=True,
        timeout=None, on_terminate=None):
        """Kill a process tree (including grandchildren) with signal
        "sig" and return a (gone, still_alive) tuple.
        "on_terminate", if specified, is a callabck function which is
        called as soon as a child terminates.
        """
        if pid == os.getpid():
        raise RuntimeError("I refuse to kill myself")
        parent = psutil.Process(pid)
        children = parent.children(recursive=True)
        if include_parent:
        children.append(parent)
        for p in children:
        p.send_signal(sig)
        gone, alive = psutil.wait_procs(children, timeout=timeout,
        callback=on_terminate)
        return (gone, alive)

        pid = find_procs_by_name('POWERPNT.EXE')[0].pid
        print(find_procs_by_name('POWERPNT.EXE')[0].pid)
        kill_proc_tree(pid)





        share|improve this answer













        How about consider using psutil, I think it is quite suitable for your case.



        As stated in document, following code can do what you want. Though you may not need the part of find_procs_by_name.



        import os
        import signal
        import psutil

        def find_procs_by_name(name):
        "Return a list of processes matching 'name'."
        ls =
        for p in psutil.process_iter(attrs=["name", "exe", "cmdline"]):
        if name == p.info['name'] or
        p.info['exe'] and os.path.basename(p.info['exe']) == name or
        p.info['cmdline'] and p.info['cmdline'][0] == name:
        ls.append(p)
        return ls

        def kill_proc_tree(pid, sig=signal.SIGTERM, include_parent=True,
        timeout=None, on_terminate=None):
        """Kill a process tree (including grandchildren) with signal
        "sig" and return a (gone, still_alive) tuple.
        "on_terminate", if specified, is a callabck function which is
        called as soon as a child terminates.
        """
        if pid == os.getpid():
        raise RuntimeError("I refuse to kill myself")
        parent = psutil.Process(pid)
        children = parent.children(recursive=True)
        if include_parent:
        children.append(parent)
        for p in children:
        p.send_signal(sig)
        gone, alive = psutil.wait_procs(children, timeout=timeout,
        callback=on_terminate)
        return (gone, alive)

        pid = find_procs_by_name('POWERPNT.EXE')[0].pid
        print(find_procs_by_name('POWERPNT.EXE')[0].pid)
        kill_proc_tree(pid)






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 16 '18 at 1:56









        MatrixTaiMatrixTai

        1,926421




        1,926421



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53282800%2fsend-a-signal-event-to-an-independent-process%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            Barbados

            How to read a connectionString WITH PROVIDER in .NET Core?

            Node.js Script on GitHub Pages or Amazon S3