annotate Demo/threads/bug.py @ 5817:48b94de85bf3 legacy-trunk

Extensive changes by AMK.
author Guido van Rossum <guido@python.org>
date Thu, 17 Jul 1997 16:29:42 +0000
parents 9af8b3991ced
children 50bbe811b344
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1637
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
1 # The following self-contained little program usually freezes with most
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
2 # threads reporting
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
3 #
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
4 # Unhandled exception in thread:
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
5 # Traceback (innermost last):
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
6 # File "importbug.py", line 6
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
7 # x = whrandom.randint(1,3)
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
8 # AttributeError: randint
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
9 #
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
10 # Here's the program; it doesn't use anything from the attached module:
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
11
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
12 import thread
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
13
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
14 def task():
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
15 global N
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
16 import whrandom
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
17 x = whrandom.randint(1,3)
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
18 a.acquire()
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
19 N = N - 1
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
20 if N == 0: done.release()
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
21 a.release()
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
22
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
23 a = thread.allocate_lock()
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
24 done = thread.allocate_lock()
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
25 N = 10
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
26
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
27 done.acquire()
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
28 for i in range(N):
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
29 thread.start_new_thread(task, ())
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
30 done.acquire()
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
31 print 'done'
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
32
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
33
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
34 # Sticking an acquire/release pair around the 'import' statement makes the
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
35 # problem go away.
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
36 #
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
37 # I believe that what happens is:
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
38 #
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
39 # 1) The first thread to hit the import atomically reaches, and executes
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
40 # most of, get_module. In particular, it finds Lib/whrandom.pyc,
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
41 # installs its name in sys.modules, and executes
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
42 #
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
43 # v = eval_code(co, d, d, d, (object *)NULL);
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
44 #
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
45 # to initialize the module.
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
46 #
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
47 # 2) eval_code "ticker"-slices the 1st thread out, and gives another thread
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
48 # a chance. When this 2nd thread hits the same 'import', import_module
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
49 # finds 'whrandom' in sys.modules, so just proceeds.
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
50 #
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
51 # 3) But the 1st thread is still "in the middle" of executing whrandom.pyc.
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
52 # So the 2nd thread has a good chance of trying to look up 'randint'
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
53 # before the 1st thread has placed it in whrandom's dict.
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
54 #
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
55 # 4) The more threads there are, the more likely that at least one of them
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
56 # will do this before the 1st thread finishes the import work.
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
57 #
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
58 # If that's right, a perhaps not-too-bad workaround would be to introduce a
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
59 # static "you can't interrupt this thread" flag in ceval.c, check it before
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
60 # giving up interpreter_lock, and have IMPORT_NAME set it & restore (plain
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
61 # clearing would not work) it around its call to import_module. To its
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
62 # credit, there's something wonderfully perverse about fixing a race via an
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
63 # unprotected static <grin>.
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
64 #
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
65 # as-with-most-other-things-(pseudo-)parallel-programming's-more-fun-
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
66 # in-python-too!-ly y'rs - tim
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
67 #
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
68 # Tim Peters tim@ksr.com
9af8b3991ced Initial revision
Guido van Rossum <guido@python.org>
parents:
diff changeset
69 # not speaking for Kendall Square Research Corp