Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!rt.uk.eu.org!newsfeed.xs4all.nl!newsfeed4.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.026 X-Spam-Evidence: '*H*': 0.95; '*S*': 0.00; 'interpreter': 0.05; 'init': 0.07; 'caller': 0.09; 'cleanup': 0.09; 'exit': 0.09; 'function,': 0.09; 'properly.': 0.09; 'cc:addr:python-list': 0.11; 'python': 0.11; 'assume': 0.14; 'thread': 0.14; 'cleans': 0.16; 'exit.': 0.16; 'fail,': 0.16; 'globals': 0.16; 'thread,': 0.16; 'threads,': 0.16; 'unexpected': 0.16; 'exception': 0.16; 'wrote:': 0.18; 'library': 0.18; 'wed,': 0.18; 'basically': 0.19; 'pfxlen:0': 0.19; 'work,': 0.20; 'cc:addr:python.org': 0.22; '(such': 0.24; 'cc:2**0': 0.24; 'least': 0.26; 'certain': 0.27; 'header:In-Reply-To:1': 0.27; "doesn't": 0.30; 'message- id:@mail.gmail.com': 0.30; 'url:mailman': 0.30; 'asked': 0.31; 'asks': 0.31; 'anyone': 0.31; 'run': 0.32; 'url:python': 0.33; 'not.': 0.33; 'actual': 0.34; 'problem': 0.35; "can't": 0.35; 'advice': 0.35; 'anywhere': 0.35; 'case,': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'there': 0.35; 'module.': 0.36; 'url:listinfo': 0.36; 'thanks': 0.36; 'possible': 0.36; 'url:org': 0.36; 'should': 0.36; 'requirements': 0.37; 'being': 0.38; 'ends': 0.38; 'issue': 0.38; 'pm,': 0.38; 'does': 0.39; 'called': 0.40; 'users': 0.40; 'url:mail': 0.40; 'ensure': 0.60; 'even': 0.60; 'skip:u 10': 0.60; 'deleting': 0.60; 'most': 0.60; 'matter': 0.61; 'simply': 0.61; 'skip:n 10': 0.64; 'chance': 0.65; 'occur': 0.65; 'temporary': 0.65; 'to:addr:gmail.com': 0.65; 'hang': 0.67; 'tasks.': 0.68; 'safe': 0.72; 'therefore': 0.72; 'banks': 0.74; 'obvious': 0.74; 'potentially': 0.81; 'case?': 0.84; 'killing': 0.84; 'spawned': 0.84; 'warnings.': 0.84 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type:content-transfer-encoding; bh=AI6Cx+PW5QGkJHGMibJzrKNkCav3dzDXJSlNfua/upo=; b=MZjNw19PaObuB7Euwc3w2HDMeAph1Awv5H5x68yd6IDIG/XJ5tofoGQFSMM2HSUDcW YutxImpqOMwcCip+53gUJkcsZHvaZQI6FscERTSFDktggg3fyhiP6M948eaEKY0QY3sE 6yPcFm+hB8VtDed4uEk175gvtAu1F9QgikNUIixE182zHp/6k+89LE0czPggc1LxsvnA 46bshUZKllH4M3OFHsGkSq7pmdafvVAD5UNV7Y77GOue0GrdesEnZtfo+8LLtIUFtcaU lVchoPJbUzdkgemnPIGpvktqW3yheTa7PZhpvklzdgPpnZnWSsc+/HSX8NqycWRmk7Yz t2EA== X-Received: by 10.224.95.73 with SMTP id c9mr25960913qan.68.1401482862396; Fri, 30 May 2014 13:47:42 -0700 (PDT) MIME-Version: 1.0 In-Reply-To: <368aec88-ebe9-4da0-a537-92ff9b690647@googlegroups.com> References: <368aec88-ebe9-4da0-a537-92ff9b690647@googlegroups.com> From: Devin Jeanpierre Date: Fri, 30 May 2014 13:47:02 -0700 Subject: Re: daemon thread cleanup approach To: Carl Banks Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Cc: "comp.lang.python" X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 52 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1401482865 news.xs4all.nl 2848 [2001:888:2000:d::a6]:53989 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:72318 Don't use daemon threads, they are inherently un-thread-safe: any global access you do anywhere inside a daemon thread can fail, because daemon threads are still potentially run during interpreter shutdown, when globals are being deleted from every module. Most functions you might call are not safe in a daemon thread at shutdown. -- Devin On Wed, May 28, 2014 at 6:20 PM, Carl Banks wrot= e: > Ok, so I have an issue with cleaning up threads upon a unexpected exit. = I came up with a solution but I wanted to ask if anyone has any advice or w= arnings. > > Basically I am writing a Python library to run certain tasks. All of the= calls in the library start worker threads to do the actual work, and some = of the worker threads are persistent, others not. Most threads have cleanu= p work to do (such as deleting temporary directories and killing spawned pr= ocesses). > > For better or worse, one of the requirements is that the library can't ca= use the program to hang no matter what, even if it means you have to forego= cleanup in the event of an unexpected exit. Therefore all worker threads = run as daemons. Nevertheless, I feel like the worker threads should at lea= st be given a fair opportunity to clean up; all threads can be communicated= with and asked to exit. > > One obvious solution is to ask users to put all library calls inside a wi= th-statement that cleans up on exit, but I don't like it for various reason= s. > Using atexit doesn't work because it's called after the daemon threads ar= e killed. > > Here's the solution I came up with: in the library's init function, it wi= ll start a non-daemon thread that simply joins the main thread, and then as= ks all existing worker threads to exit gracefully before timing out and lea= ving them to be killed. So if an exception ends the main thread, there is = still a chance to clean up properly. > > Does anyone see a potential problem with this approach? It it possible t= hat this will cause the program to hang in any case? We can assume that al= l calls to the library will occur from the main thread, or at least from th= e same thread. (If that isn't the case, then the caller has taken responsi= bility to ensure the program doesn't hang.) > > This is Python 2.7, and it's only ever going to run on Windows. > > Thanks for any advice/warnings. > > Carl Banks > -- > https://mail.python.org/mailman/listinfo/python-list