1

I'm attempting to start a process for item in list using an if statement. The if statement (if condition met) will call a function passing in 2 args. The function then iterates through another list running a subprocess call for each in the list. Now for some reason I'm not getting any output from the subprocess. If I run the same command in the command line it works fine, and it worked fine before I started down the multiprocessing road. Could anyone kindly explain whats going on?

This is how the function is being called.

userlist = (name1, name2, name3)
if condition == True:
    for user in userlist: 
        p = multiprocessing.Process(target=tllocaltF, args=(serverlist, user))
        jobs.append(p)
        p.start()  

this is the function it is calling:

def tllocaltF(domain, user):
#function iterates list of target users locally
    print (domain,user) #this prints out the username and domain as expected
    print "Targeted Users Found On LocalHost\n"
    try:
        out = subprocess.check_output(["tasklist", "/V", "/FO", "List", "/FI", "USERNAME eq {0}\\{1}" .format(domain, user)], stderr=subprocess.STDOUT)
        users = [item for item in out.split() if domain in item and user in item]
        sortedl = set(users)
        print sortedl #this is printing set([])
        for item in sortedl: 
            print item
    except CalledProcessError as e:
        errormessage = e.output
        print errormessage

    print "\nCompleted"    
Joseph Quinsey
  • 9,553
  • 10
  • 54
  • 77
iNoob
  • 1,375
  • 3
  • 19
  • 47
  • if i `print out` i get the following: INFO: No tasks are running which match the specified criteria. So what is the multiprocess instance doing to the command? – iNoob Mar 27 '14 at 01:15
  • How are you running this code? i.e. in what environment? There are various bugs/issues related to printing in child processes in certain environments. – roippi Mar 27 '14 at 01:43
  • Im running the code on windows 7 – iNoob Mar 27 '14 at 01:44
  • Sorry wing ide on windows 7 – iNoob Mar 27 '14 at 01:45

1 Answers1

2

You won't see any output from a function called through multiprocessing.Subprocess() because that function launches an entirely separate process that has its own stdin and stdout which are not connected to the command prompt/terminal of the parent process. You have a few options:

1) Change your print statements in tllocaltF() to write to temporary files instead of printing. This isn't a long-term solution, but can be a helpful debugging step to be sure your subprocess code is actually executing the way you think it is. You should be able to see your subprocess dropping text files in lieu of printing to stdout. If you don't see the text files appear, then your function may not be executing at all.

2) Implement a method like this, which is very similar to this SO question, to capture the output from your subprocesses.

3) Place your subprocesses' output on a pipe or queue to be retrieved and printed out by your main process.

4) Since you're launching subprocesses to handle portions of an iterable, you may also want to consider using a multiprocessing pool:

import multiprocessing
import functools

if condition == True:

    # use functools.partial() to create a new function that always has the same first
    # argument - it seems to me that your code always calls tllocaltF() with the same
    # serverlist argument, so we're going to create a new function that doesn't need
    # serverlist to be explicitly passed every time - this is required to use 
    # multiprocessing.map()

    single_argument_function = functools.partial(tllocaltF, serverlist)

    pool = multiprocessing.Pool()
    results = pool.map(single_argument_function, userList) # blocking call

    # don't forget to clean up
    pool.close()
    pool.join()

This code snippet will do the same thing that you were already doing, but this method of launching subprocesses will alleviate your whole output issue - your subprocesses (when launched this way) will use the same stdout as the parent process. If you don't want to wait for the results, you can use multiprocessing.map_async() (it is non-blocking) and check the results object later.

Community
  • 1
  • 1
skrrgwasme
  • 9,358
  • 11
  • 54
  • 84