Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Add GetPythonThreadID and Interrupt methods in PythonEngine#1337

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
lostmsu merged 4 commits intopythonnet:masterfromgpetrou:Interrupt
Jan 21, 2021

Conversation

gpetrou
Copy link
Contributor

@gpetrougpetrou commentedDec 26, 2020
edited
Loading

What does this implement/fix? Explain your changes.

Fixes#766 by adding an Interrupt method in PythonEngine class.

Checklist

Check all those that are applicable and complete.

  • Make sure to include one or more tests for your change
  • If an enhancement PR, please create docs and at best an example
  • Add yourself toAUTHORS
  • Updated theCHANGELOG

@gpetrougpetrouforce-pushed theInterrupt branch 9 times, most recently from9b35013 tod075db3CompareDecember 26, 2020 16:34
@filmor
Copy link
Member

Copying my comment from#1333:

  1. This requires a test (done)
  2. Strictly, the thread-id attribute is unsigned only for Python >= 3.7 and we still support 3.6
  3. Also, since the original type is long, the "correct" type is (U)IntPtr on everything but Windows (Not quite sure how far we have to go there compatibility-wise, the current implementation could be fine for the usual thread IDs)
  4. Maybe we should just expose the API function directly (i.e. RaiseInPythonThread on Exception objects or so) and make Interrupt use that

Additional comments on the current state: The helper API to get the current thread id should be in the library and should usethreading.get_native_id() on Python >=3.8.

@filmor
Copy link
Member

It would also be good if you'd just use normal commits now without force-pushing a single commit over and over, otherwise it becomes very difficult to follow your changes. We can (and will) squash this in the end.

@gpetrou
Copy link
ContributorAuthor

Please note that I am very unfamiliar with the codebase, so I will need more explanations from you. With regards to:
2. I added a version check. Is this what you mean?
3. I added different calls per OS and version. Is this what you mean?
4. I don't understand what that means. Can you elaborate? Is this still needed?

@gpetrougpetrouforce-pushed theInterrupt branch 3 times, most recently from07b9655 toc3f7c78CompareDecember 27, 2020 07:17
if (Runtime.PyVersion >= new Version(3, 8))
{
dynamic threading = Py.Import("threading");
return threading.get_native_id();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Should get theGIL, I think.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Isn't the user supposed to do that when calling the method, as I did in the test?

Copy link
ContributorAuthor

@gpetrougpetrouDec 27, 2020
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

This does not seem to be working on Ubuntu. Are you sure that this should work? Looking in CPython tests I see that get_ident is used. I don't see any benefit in adding the above lines. Should I just remove them?

@filmor
Copy link
Member

This goes in the right direction :)

Regarding 2.: Yes, that's what I meant.
Regarding 3.: This looks better, but the Windows type isuint andint. .NET'sint is always 32bit, and on Windowslong is also 32bit on both x86 and x64.

@gpetrougpetrouforce-pushed theInterrupt branch 8 times, most recently fromfb52aa3 to90a08b6CompareDecember 31, 2020 09:08
@gpetrou
Copy link
ContributorAuthor

@filmor can this be merged now?

@@ -2143,6 +2143,18 @@ internal static void Py_CLEAR(ref IntPtr ob)
[DllImport(_PythonDll, CallingConvention = CallingConvention.Cdecl)]
internal static extern int Py_AddPendingCall(IntPtr func, IntPtr arg);

[DllImport(_PythonDll, EntryPoint = "PyThreadState_SetAsyncExc", CallingConvention = CallingConvention.Cdecl)]
internal static extern int PyThreadState_SetAsyncExc37Windows(uint id, IntPtr exc);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Why do you need overloads withuint andint? They are basically equivalent at bit level.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I added them because of "Strictly, the thread-id attribute is unsigned only for Python >= 3.7 and we still support 3.6" comment above. Do you want me to remove them?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@filmor on the binary side there's no difference. The caller, if necessary, can bitcast. Any thoughts?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I have removed the int and long declarations for now.

Comment on lines 583 to 578
public static ulong GetNativeThreadID()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return GetCurrentThreadId();
}

if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
return pthread_selfLinux();
}

if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
return pthread_selfOSX();
}

throw new InvalidOperationException("Could not retrieve native thread ID.");
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I don't think this belongs toPythonEngine. From what I read, for the test you might be able to usethreading.get_ident() from Pythonthread module.

Copy link
Member

@filmorfilmorDec 31, 2020
edited
Loading

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

get_ident is a separate thing, the IDs are not compatible with the "remote raise".

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@filmor are you sure? Documentation is very bad on this, but here's what I found:

get_identappears to be returningPyThread_get_thread_ident
tstate->thread_idis alsoPyThread_get_thread_ident()

PyThreadState_SetAsyncExcfinds thread by itststate->thread_id

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Using get_ident seems to work. What would you like me to do? Modify GetNativeThreadID method or remove it completely?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Remove it would be better.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@lostmsu You are right. But then we should still exposethreading.get_ident orPyThread_get_thread_ident, no?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Why? The user can do what tests do now - e.g. callPy.Import("threading").Invoke("get_ident").

@gpetrou It might make sense to mentionthreading.get_ident() in the summary of XML doc for theInterrupt method.

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

I am getting mixed signals between the two of you :) Who is the BDFL for Python.NET? I added the get_ident usage in GetNativeThreadID for now.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

@gpetrou@filmor well, I am voting for removal, as it is one less thing to support with potential multiple meanings, and having nothing to do with Python embedding on itself.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

CHANGELOG.md Outdated
@@ -10,6 +10,7 @@ This document follows the conventions laid out in [Keep a CHANGELOG][].
### Added

- Ability to instantiate new .NET arrays using `Array[T](dim1, dim2, ...)` syntax
- Add GetNativeThreadID and Interrupt methods in PythonEngine
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

GetNativeThreadID should be gone now

@gpetrougpetrouforce-pushed theInterrupt branch 2 times, most recently fromce3d6b4 to9b18f26CompareJanuary 8, 2021 07:00
@@ -582,28 +573,8 @@ public static void Exec(string code, IntPtr? globals = null, IntPtr? locals = nu
/// <returns>The native thread ID.</returns>
public static ulong GetNativeThreadID()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

If we keep this, it should be renamed toGetPythonThreadId and doesn't this require the GIL in general?

Copy link
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Can you please explain why we need GIL here and not in the Interrupt method? GIL is used for both in the tests already.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Actually, you are right, all of the other functions in here require theGIL to be taken explicitly as well. I'm not terribly happy about this, but this should be fine then. Thedynamic here should not be required, just useInvokeMethod:

var threading = ...;return threading.InvokeMethod("get_ident");

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

And renaming would still be nice, sorry for the back and forth, I misread the docs.

@gpetrougpetrou changed the titleAdd Interrupt method in PythonEngineAdd GetPythonThreadID and Interrupt methods in PythonEngineJan 21, 2021
@gpetrougpetrouforce-pushed theInterrupt branch 2 times, most recently from6bcda67 toc455ee4CompareJanuary 21, 2021 09:00
@lostmsulostmsu merged commit5fd77b1 intopythonnet:masterJan 21, 2021
lostmsu added a commit to losttech/pythonnet that referenced this pull requestFeb 21, 2021
lostmsu added a commit to losttech/pythonnet that referenced this pull requestFeb 21, 2021
lostmsu added a commit to losttech/pythonnet that referenced this pull requestFeb 21, 2021
lostmsu added a commit to losttech/pythonnet that referenced this pull requestFeb 21, 2021
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@filmorfilmorfilmor left review comments

@lostmsulostmsulostmsu requested changes

Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

Interrupting running Python code from another thread
3 participants
@gpetrou@filmor@lostmsu

[8]ページ先頭

©2009-2025 Movatter.jp