On Thu, 27 Jun 2019 at 20:53, Yonatan Zunger <zun...@humu.com> wrote:

> Generally, threads don't have a notion of non-cooperative thread
> termination. This is because (unlike processes) threads share address
> spaces, and an unexpected termination of a thread can leave memory in
> arbitrary and unexpected states. (For example, what if one thread was
> holding a mutex when it got killed?)
>

That's precisely why thread cancellation in managed languages (like Python
is) raise an exception to terminate the the thread and honour finally
blocks.




> The POSIX threading model *does* include the ability to send a signal to
> a particular thread using pthread_kill(). What that does is cause the
> process' globally-registered signal handler for that signal to be invoked
> in that particular thread. With the default handlers, though, these tend to
> have process-wide effects; e.g., if you pthread_kill(tid, 15) with the
> default handler, it will simply kill the process. This doesn't make as much
> sense in the context of Python's signal handling (which is a layer on top
> of POSIX signal handling) so signals.pthread_kill() isn't a very useful
> function.
>


This is not what is being suggested. Read about the semantics of thread
killing in C# and Java.


> In practice (and I actually had to deal with exactly this problem in my
> own code just last week!) there are two approaches that tend to work:
>


Yet again someone who doesn't understand what is being proposed saying it
isn't needed.

Michael


> (1) Cooperative scheduling: Your code has an explicit place within the
> threads where they check for abort signals and handle them appropriately.
> For example, if your threads are each running event listeners, you might
> post a "cancel" event on the main bus; or alternately, you could use a
> threading.Event to signal everyone to shut down.
>
> (2) Separate address spaces: If (1) isn't possible for some reason, and
> you need to literally be able to kill off a process noncooperatively --
> say, the purpose of your code is to be an intermediate "harness" library
> which runs someone else's long-running functions in a thread, and it's not
> possible to require all of that code to obey a cooperative protocol -- then
> use processes instead of threads.
>
> In many cases, you can achieve this with built-in Python libraries like
> multiprocessing and ProcessPoolExecutor, and in this case, you can
> terminate processes simply by calling Popen.send_signal() or the like. In a
> few cases (e.g., if you're using gRPC, whose client library is incompatible
> with those for complicated reasons) you'll have to fork() and exec()
> yourself, typically by using the subprocess.Popen library directly.
>
> Yonatan
>
> On Thu, Jun 20, 2019 at 10:16 AM Michael Foord <fuzzy...@gmail.com> wrote:
>
>>
>>
>> On Thu, 20 Jun 2019 at 16:33, Guido van Rossum <gu...@python.org> wrote:
>>
>>> On Thu, Jun 20, 2019 at 8:21 AM Michael Foord <fuzzy...@gmail.com>
>>> wrote:
>>> > It works by raising an exception in the target thread, which the
>>> thread is free to handle (usually for cleanup and then reraise).
>>>
>>> Sure, those are the right semantics. How does it stop blocking I/O
>>> though? Suppose the thread is waiting for a server to return a response
>>> which just isn't ever going to come, but the connection somehow is kept
>>> open by the other side?
>>>
>>
>>
>>
>> Sorry, resending to list as well.
>>
>>
>>
>> It used to be on the CLR getting back control. So it couldn't handle that
>> case. (.NET 1.1).
>>
>> https://jonskeet.uk/csharp/threads/abort.html
>>
>> It has since been improved. It still blocks on the execution of unmanaged
>> code (or computation in a finally block handling the ThreadAbortException),
>> but blocking IO can be interrupted:
>>
>>
>> https://docs.microsoft.com/en-us/dotnet/api/system.threading.thread.abort?view=netframework-4.8
>>
>> If Abort is called on a thread that is blocked or is sleeping, the
>> thread is interrupted and then aborted.
>>
>> This SO question on the topic says:
>>
>> https://stackoverflow.com/questions/365370/proper-way-to-stop-tcplistener
>>
>>
>> Thread.Abort()
>>
>> There are 2 things I see you could do. 1 is that if you have started this
>> TcpListener thread from another you can simply call Thread.Abort instance
>> method on the thread which will cause a threadabortexception to be thrown
>> within the blocking call and walk up the stack.
>>
>> Michael
>>
>>
>>>
>>> --
>>> --Guido van Rossum (python.org/~guido)
>>> Pronouns: he/him/his (why is my pronoun here?)
>>>
>> --
>>
>> Michael Foord
>>
>> Python Consultant, Contractor and Trainer
>>
>> https://agileabstractions.com/
>>
>> _______________________________________________
>> Python-ideas mailing list -- python-ideas@python.org
>> To unsubscribe send an email to python-ideas-le...@python.org
>> https://mail.python.org/mailman3/lists/python-ideas.python.org/
>> Message archived at
>> https://mail.python.org/archives/list/python-ideas@python.org/message/ARIZ3WMWXIP6MICQFW3OKE4VY43OKXEK/
>
>
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
> --

Michael Foord

Python Consultant, Contractor and Trainer

https://agileabstractions.com/
_______________________________________________
Python-ideas mailing list -- python-ideas@python.org
To unsubscribe send an email to python-ideas-le...@python.org
https://mail.python.org/mailman3/lists/python-ideas.python.org/
Message archived at 
https://mail.python.org/archives/list/python-ideas@python.org/message/PB5SX3BRODO5TYK63RBETXOF4CJCGPPF/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to