psutil - suspending process - python

I'm writing a script in Python for Linux that should suspend process when given conditions are met and later resume it. To do so I'm using psutil (http://code.google.com/p/psutil).
The problem I encountered is rather strange. When I use python command line, everything works fine - process is suspended and later resumed. However, when I use the same function in a script file and then I try to run it, it throws exception:
AttributeError: 'Process' object has no attribute 'suspend'
Snippet of code:
p = psutil.Process(19931)
p.suspend()
print 'suspended'
time.sleep(10)
p.resume()
print 'resumed'
Of course 19931 is typed PID of the process I've started in background and want it to be suspended.
Does anyone have some ideas or hints? Psutil is the newest version installed from Google code.

I know its an old entry but for the ones who encountered this problem recently,
this code works fine for me (Python 3.7.3) :
psutil.Process(pid=19931).suspend()
And similarly
psutil.Process(pid=19931).resume()
But you have to be sure that referred process is still alive.

The first thing I would suspect when Python behaves differently under the interactive shell and executing a script would be running different versions of Python. This can easily happen when you point to an interpreter in your script file with something like:
#!/usr/bin/python
This is a long shot since, according to the psutil website, it's supposed to work well with Python versions from 2.4 to 3.3. Also, your snippet works fine on my machine (kernel 2.6.32, Python 2.6.6).

Related

Python Process (Activity Monitor) Doesn't Stop

I recently started using Python. I realized that even the simplest program starts a Python process that never ends and causes my computer to overheat if I don't manually kill that process.
I've even seen multiple Python processes running at the same time after running a few easy Python programs (Hello, World!) in a row.
I updated to the latest Python version (Python 3.9.3), installed all the Certificates, and tested a few different programs to see if it happens every time—it does. I am using VSC as the IDE but the same situation happens even if I use IDLE.
My questions are: Is this an interpreter issue or a Mac issue? Can it be fixed?
Thank you very much.

Python script getting stuck in between without any trace

I have a python script which is threaded and runs on our server node . The Problem is that the script gets stuck/hanged without any trace.
How to check where the script is hanging as it doesn't print anything
Take a look at the hanging_threads module (available from PyPI) - It might give you some pointers on where your code gets stuck. However it is prone to false positives (e.g. if your script waits for a network connection).

What's the difference between coding in the IDLE and the terminal?

I installed python 2.7 and I have the IDLE version of it. I also created two environments using the terminal of Python 3 and Python 2 with conda.
When I type python it shows me that I'm using Python 3.5.2. Now:
How can I switch between two versions in the IDLE or the terminal?
What's the difference between coding in the IDLE or the terminal?
You cannot switch versions of Python from within Python. IDLE runs on top of whatever version of Python, and cannot switch the version running it. You can simultaneously run IDLE 2.7 on Python 2.7 and IDLE 3.5 on Python 3.5.
When you run code from any IDLE editor, it is added your File => Recent files list, which is used for any version of IDLE you run. I frequently pull a file into another running version to see if it runs the same, perhaps after revision for known differences between 2.7 and 3.x.
At least 95% of code that people write runs the same directly in Python (with the -i flag) and IDLE. The IDLE doc, accessible under Help => IDLE Help, notes these differences.
3.2. IDLE-console differences
As much as possible, the result of executing Python code with IDLE is
the same as executing the same code in a console window. However, the
different interface and operation occasionally affects visible
results. For instance, sys.modules starts with more entries.
IDLE also replaces sys.stdin, sys.stdout, and sys.stderr with objects
that get input from and send output to the Shell window. When this
window has the focus, it controls the keyboard and screen. This is
normally transparent, but functions that directly access the keyboard
and screen will not work. If sys is reset with importlib.reload(sys),
IDLE’s changes are lost and things like input, raw_input, and print
will not work correctly.
With IDLE’s Shell, one enters, edits, and recalls complete statements.
Some consoles only work with a single physical line at a time. IDLE
uses exec to run each statement. As a result, 'builtins' is
always defined for each statement.
There are probably a few more equally esoteric things I should add.
IDLE has this feature where it suggests operations on a variable automatically or by using ctrl+space. But in terminal no such suggestion prompts appear in any case.
Not sure how you can switch versions in terminal.

launch external shell python instance in shell from python

I'd like to call a separate non-child python program from a python script and have it run externally in a new shell instance. The original python script doesn't need to be aware of the instance it launches, it shouldn't block when the launched process is running and shouldn't care if it dies. This is what I have tried which returns no error but seems to do nothing...
import subprocess
python_path = '/usr/bin/python'
args = [python_path, '&']
p = subprocess.Popen(args, shell=True)
What should I be doing differently
EDIT
The reason for doing this is I have an application with a built in version of python, I have written some python tools that should be run separately alongside this application but there is no assurance that the user will have python installed on their system outside the application with the builtin version I'm using. Because of this I can get the python binary path from the built in version programatically and I'd like to launch an external version of the built in python. This eliminates the need for the user to install python themselves. So in essence I need a simple way to call an external python script using my current running version of python programatically.
I don't need to catch any output into the original program, in fact once launched I'd like it to have nothing to do with the original program
EDIT 2
So it seems that my original question was very unclear so here are more details, I think I was trying to over simplify the question:
I'm running OSX but the code should also work on windows machines.
The main application that has a built in version of CPython is a compiled c++ application that ships with a python framework that it uses at runtime. You can launch the embedded version of this version of python by doing this in a Terminal window on OSX
/my_main_app/Contents/Frameworks/Python.framework/Versions/2.7/bin/python
From my main application I'd like to be able to run a command in the version of python embedded in the main app that launches an external copy of a python script using the above python version just like I would if I did the following command in a Terminal window. The new launched orphan process should have its own Terminal window so the user can interact with it.
/my_main_app/Contents/Frameworks/Python.framework/Versions/2.7/bin/python my_python_script
I would like the child python instance not to block the main application and I'd like it to have its own terminal window so the user can interact with it. The main application doesn't need to be aware of the child once its launched in any way. The only reason I would do this is to automate launching an external application using a Terminal for the user
If you're trying to launch a new terminal window to run a new Python in (which isn't what your question asks for, but from a comment it sounds like it's what you actually want):
You can't. At least not in a general-purpose, cross-platform way.
Python is just a command-line program that runs with whatever stdin/stdout/stderr it's given. If those happen to be from a terminal, then it's running in a terminal. It doesn't know anything about the terminal beyond that.
If you need to do this for some specific platform and some specific terminal program—e.g., Terminal.app on OS X, iTerm on OS X, the "DOS prompt" on Windows, gnome-terminal on any X11 system, etc.—that's generally doable, but the way to do it is by launching or scripting the terminal program and telling it to open a new window and run Python in that window. And, needless to say, they all have completely different ways of doing that.
And even then, it's not going to be possible in all cases. For example, if you ssh in to a remote machine and run Python on that machine, there is no way it can reach back to your machine and open a new terminal window.
On most platforms that have multiple possible terminals, you can write some heuristic code that figures out which terminal you're currently running under by just walking os.getppid() until you find something that looks like a terminal you know how to deal with (and if you get to init/launchd/etc. without finding one, then you weren't running in a terminal).
The problem is that you're running Python with the argument &. Python has no idea what to do with that. It's like typing this at the shell:
/usr/bin/python '&'
In fact, if you pay attention, you're almost certainly getting something like this through your stderr:
python: can't open file '&': [Errno 2] No such file or directory
… which is exactly what you'd get from doing the equivalent at the shell.
What you presumably wanted was the equivalent of this shell command:
/usr/bin/python &
But the & there isn't an argument at all, it's part of sh syntax. The subprocess module doesn't know anything about sh syntax, and you're telling it not to use a shell, so there's nobody to interpret that &.
You could tell subprocess to use a shell, so it can do this for you:
cmdline = '{} &'.format(python_path)
p = subprocess.Popen(cmdline, shell=True)
But really, there's no good reason to. Just opening a subprocess and not calling communicate or wait on it already effectively "puts it in the background", just like & does on the shell. So:
args = [python_path]
p = subprocess.Popen(args)
This will start a new Python interpreter that sits there running in the background, trying to use the same stdin/stdout/stderr as your parent. I'm not sure why you want that, but it's the same thing that using & in the shell would have done.
Actually I think there might be a solution to your problem, I found a useful solution at another question here.
This way subprocess.popen starts a new python shell instance and runs the second script from there. It worked perfectly for me on Windows 10.
You can try using screen command
with this command a new shell instance created and the current instance runs in the background.
# screen; python script1.py
After running above command, a new shell prompt will be seen where we can run another script and script1.py will be running in the background.
Hope it helps.

subprocess running python getting import error

I'm trying to run a python script from a python program by kicking it off from subprocess (The reason is that the main program has to have exited when the script runs, with a combination of wx.CallAfter and Close). However when the script runs I get an error on line 1 with ImportError: No module named os which makes me think it's something to do with the PythonPath, but I can run the script just fine from a terminal.
Why can't the script see any core modules when run this way?
Edit:
The line in question is:
wx.CallAfter(subprocess.Popen,'python %s "%s" %s %s'%(os.path.join(BASE_DIR,"updatecopy.py"),BASE_DIR,pos[0],pos[1]),shell=True)
BASE_DIR is just the directory that the script lives in.
subprocess is there because os.exec* has been deprecated so I wouldn't suggest using that in place of Popen as someone suggested.
I've seen this issue crop up when running from a frozen process. If that is the case then you're most likely inheriting a weird environment for the new python process.
Most frozen scripts will be trying to run from a zip file, in which case it's no wonder that Python can't find anything, it's all trapped in a zip file :)
If this is the situation then try running using the python executable that you are using to run the frozen script. It should be able to deal with the special environment.
Maybe you could use os.execv instead of Popen.
From os/python docs:
These functions all execute a new program, replacing the current process; they do not return. On Unix, the new executable is loaded into the current process, and will have the same process id as the caller. Errors will be reported as OSError exceptions.
(emphasis mine)

Categories

Resources