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/