Skip to content

Adding thread state storage for embedders  #1215

Closed

Description

@bmiller-pm

Environment

  • Pythonnet version: 3.0.0
  • Python version: 3.x
  • Operating System: Windows 10, + others

Details

  • I need access to the PyThreadState_GetDict cpython call.

    I have embedded Python.Net in my app but since I have multiple threads (tasks) running scripts and calling back into C#, I require a way to store my thread context into the current Python thread.
    To to this I imported PyThreadState_GetDict myself (worked fine), but I also needed the other low level cpython calls that are set as internal in the Python.Runtime class.

So here would be the new member exposed by Python.Runtime (or somewhere)

public PyDict GetThreadStateDict()
{
	IntPtr dict = Runtime.PyThreadState_GetDict();
	Runtime.XIncref(dict); // borrowed ref
	return new PyDict(dict);
}

And, then we can get & set an object of some kind

protected ScriptContext GetContext()
{
	using (var tdict = GetThreadStateDict())
	{
		using (PyObject context_key = tdict.GetItem(_thread_cookie_name_s))
		{
			return (ScriptContext)context_key.AsManagedObject(typeof(ScriptContext));
		}
	}
}

protected void SetContext(ScriptContext context)
{
	using (var tdict = GetThreadStateDict())
	{
		tdict.SetItem(_thread_cookie_name_s, context.ToPython());
	}
}

That is, unless there's a better way to keep track of what original thread is calling back into the app.
Maybe the Python Thread Specific Storage (TSS) API would be better?

Activity

  1. lostmsu commented on Sep 2, 2020

    @lostmsu
    Member

    @quickwire is there any reason you can not use .NET ThreadLocal<T> or any similar class from Python standard library?

  2. bmiller-pm commented on Sep 3, 2020

    @bmiller-pm
    Author

    ok, you're right, I just implemented ThreadLocal and it works better & faster in one line.
    I'm porting from c++, a c++ object was stored in the python thread state dict in the older app. I just basically copied the same implementation.
    So no need for Python.Runtime internal access either.
    Thanks for taking the time and pointing out something that should have been obvious to me...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions