Sorry for the rude tone of part of that email.

Sent from my iPhone

> On 27 Jun 2019, at 23:36, Michael Foord <fuzzy...@gmail.com> wrote:
> 
> 
> 
>> 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/52ZUBIQS5TTSK64NTXDLICTLX47ZDRIM/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to