Skip to content

Crash when I try to open multiple plot windows #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ThisIsACreativeName opened this issue Oct 15, 2015 · 1 comment
Open

Crash when I try to open multiple plot windows #2

ThisIsACreativeName opened this issue Oct 15, 2015 · 1 comment

Comments

@ThisIsACreativeName
Copy link

First of all, I really enjoy using your matplotlib-cpp wrapper thingy. So thank you for your effort.

I try to show multiple plots in different windows simultaneously. But as soon as I show() a second plot the application crashes.
A colleague of mine said it could be connected to the blocking behavior of the show function (as far as I understood blocking usally means the execution is stopped till the plot window is closed. Maybe this is the case for python, but my C++ code keeps running, so maybe there's the conflict?).
When I close the window first and then open another or the same plot again via show() everything is fine.

I tried to manipulate the code in the header file a bit to pass an optional argument (and I think optional is the critical point) containing ...
block=False
... to the original python matplotlib. But I didn't suceed and it keeps crashing. I tried the following code:

PyObject* args = PyDict_New();
PyDict_SetItemString(args, "block", PyBool_FromLong(0));

PyObject* res = PyObject_CallObject(detail::_interpreter::get().s_python_function_show, args);
if(!res) throw std::runtime_error("Call to show() failed.");

Unfortunately I have no idea what else I could try to pass those optional arguments.

So maybe you can find the problem causing the crashes when opening more than one plot-window, or you can tell me how to pass working optional arguments such as "block"?
Thank you very much in advance!

Regards,
Patrick

@lava
Copy link
Owner

lava commented Oct 16, 2015

Your function is almost right, it should look like this:

inline void show_async()
{
    PyObject* kwargs = PyDict_New();
    PyDict_SetItemString(kwargs, "block", Py_False);

    PyObject* res = PyObject_Call(
        detail::_interpreter::get().s_python_function_show,
        detail::_interpreter::get().s_python_empty_tuple,
        kwargs);

    if(!res) throw std::runtime_error("Call to show() failed.");

    Py_DECREF(kwargs);
    Py_DECREF(res);
}

However, it's not as useful as you might think: As is hinted in the TODO, i never got around to wrapping the object-based interface, so currently everything just uses the global "current" axis and "current" plot. That means if you call show_async() multiple times it will plot everything in the same window.

I'm assuming you somehow use multithreading to call multiple show() commands simultaneously (since at least on my machine, it's definitely blocking), one thing to keep in mind there is that python is inherently racy and there is no way to fix it (it comes from a time when CPU's only had 1 core), so all parallel calls into the library need to be protected by some global mutex. Maybe your crash is related to that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants