Path: csiph.com!newsfeed.hal-mli.net!feeder3.hal-mli.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!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.024 X-Spam-Evidence: '*H*': 0.95; '*S*': 0.00; 'python,': 0.02; 'objects,': 0.09; 'read-only': 0.09; 'cc:addr:python-list': 0.11; 'python': 0.11; 'stored': 0.12; 'thread': 0.14; 'builtins': 0.16; 'carefully.': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris angelico': 0.16; 'guessing': 0.16; 'heap,': 0.16; 'highlight': 0.16; 'igor': 0.16; 'implies': 0.16; 'mutable': 0.16; 'namespace;': 0.16; 'objects.': 0.16; 'protecting': 0.16; 'refactoring': 0.16; 'shared.': 0.16; 'sqlite': 0.16; 'stuff,': 0.16; 'threads,': 0.16; 'time).': 0.16; 'wrote:': 0.18; 'variable': 0.18; 'normally': 0.19; 'stack': 0.19; 'thu,': 0.19; 'starts': 0.20; 'work,': 0.20; 'help.': 0.21; '(in': 0.22; 'cc:addr:python.org': 0.22; 'this?': 0.23; 'fine': 0.24; 'cc:2**0': 0.24; 'sort': 0.25; 'header:In-Reply-To:1': 0.27; 'function': 0.29; "doesn't": 0.30; 'database,': 0.30; 'dec': 0.30; 'message-id:@mail.gmail.com': 0.30; "i'm": 0.30; 'code': 0.31; 'that.': 0.31; 'there.': 0.32; 'figure': 0.32; 'another': 0.32; 'sense': 0.34; 'could': 0.34; "can't": 0.35; 'objects': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'there': 0.35; 'really': 0.36; 'executing': 0.36; 'ones,': 0.36; 'should': 0.36; 'changing': 0.37; 'so,': 0.37; 'too': 0.37; 'problems': 0.38; 'pm,': 0.38; 'rather': 0.38; 'anything': 0.39; '12,': 0.39; 'how': 0.40; 'dangerous': 0.60; 'problems.': 0.60; 'solve': 0.60; 'most': 0.60; 'hope': 0.61; 'matter': 0.61; 'more': 0.64; 'finish': 0.65; 'worth': 0.66; 'between': 0.67; 'importantly,': 0.68; 'sharing': 0.69; 'connection.': 0.74; 'guaranteed': 0.75; 'introduce': 0.78; 'protect': 0.79; 'closes': 0.84; 'confusion.': 0.84; 'data;': 0.84; 'effectively,': 0.84; "everything's": 0.84; 'isolate': 0.84; 'safe.': 0.84; 'shared,': 0.84; 'system:': 0.91; 'to:none': 0.92; 'connection,': 0.95; '2013': 0.98 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:cc :content-type; bh=jNPpqWfimkOJvHv2DrXKSDJIzcrl17CsvZrKzxDr/0Y=; b=te/tleerKLRNdLOCoGheJo8STqG6yIUaLmQ7b55fx3waf/dMUe5SCr/B5+Fq14bvtI srq96dIJmWLfumZOQI6e8Rn6wF7u3AGITGgXSjtB3gkyr9RxR0fpNqfq+Mii9TuoDZ69 IIOGjLnBHWtDda31+dxDBEN129iv0KVHsHiZ3HVmfJMJ7XuZkIk7eJ4eYJt8JiYHU8ZF cXO9TIpxRM4REMRBucEqav4gYA8jCVFBQLMRar2Rf+We1FQBtR3tvAIFANLFwXm8TC9w lhXE4GxCYd+deZX1jP/sAG3o2a5KE7qnqs5XS6n1sssfxv80jWaOSBxAeoKutuNlI+c4 OpWA== MIME-Version: 1.0 X-Received: by 10.68.173.132 with SMTP id bk4mr8541670pbc.169.1386828337912; Wed, 11 Dec 2013 22:05:37 -0800 (PST) In-Reply-To: References: Date: Thu, 12 Dec 2013 17:05:37 +1100 Subject: Re: Strange crashes From: Chris Angelico Cc: "python-list@python.org" Content-Type: text/plain; charset=UTF-8 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: 47 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1386828347 news.xs4all.nl 2829 [2001:888:2000:d::a6]:35316 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:61668 On Thu, Dec 12, 2013 at 4:47 PM, Igor Korot wrote: > So, when I find the culprit variable what do I do? > Make it a part of some class? Protect it with mutex? > > How to solve this? And most importantly, how do _I_ verify that its solved? >From the look of the error, protecting it with a mutex won't help. I'm guessing you have multiple threads sharing work, which I hope implies that your work is I/O bound rather than CPU bound (in CPython, normally only one thread will be executing Python code at a time). If those threads are casually sharing objects, you are going to have a LOT of problems. What you need to do is isolate it down so there are three groups of objects in the system: 1) Global read-only objects. This includes all your builtins and stuff, these are fine and safe. It doesn't matter that the 'len' function is shared across all your threads, because nobody's changing anything in it. 2) Per-thread objects. At no time do these ever go into any sort of global namespace; they're always function-local. Again, these are also guaranteed safe, because there's no way any other thread can tamper with them. 3) Shared, mutable objects. These are your dangerous ones, the ones you need to watch carefully. Since SQLite objects can't (apparently) be shared, it makes most sense to lock them into group 2. A thread acquires an SQLite connection, uses it, closes it, and that's that. Nothing shared. If another thread wants the database, it should create its own independent connection. If your code is too complicated to be able to figure out which category everything's in, it might be worth de-threading it temporarily. Call each thread-function one by one - effectively, have one thread finish before another thread starts - and then start refactoring from there. It might help. Alternatively, you could try switching to multiprocessing, which might highlight problems more visibly, but that might just introduce more confusion. It's really a matter of code discipline. In C, the distinction would be between stack and global/heap data; in Python, everything's stored on the heap, but there's still the same distinction. It's worth keeping straight which is which. ChrisA