Tim Peters | aa22223 | 2001-05-22 09:34:27 +0000 | [diff] [blame] | 1 | # This is a variant of the very old (early 90's) file |
| 2 | # Demo/threads/bug.py. It simply provokes a number of threads into |
| 3 | # trying to import the same module "at the same time". |
| 4 | # There are no pleasant failure modes -- most likely is that Python |
| 5 | # complains several times about module random having no attribute |
| 6 | # randrange, and then Python hangs. |
| 7 | |
| 8 | import thread |
| 9 | |
| 10 | critical_section = thread.allocate_lock() |
| 11 | done = thread.allocate_lock() |
| 12 | |
| 13 | def task(): |
| 14 | global N, critical_section, done |
| 15 | import random |
| 16 | x = random.randrange(1, 3) |
| 17 | critical_section.acquire() |
| 18 | N -= 1 |
| 19 | if N == 0: |
| 20 | done.release() |
| 21 | critical_section.release() |
| 22 | |
| 23 | # Tricky, tricky, tricky. |
| 24 | # When regrtest imports this module, the thread running regrtest grabs the |
| 25 | # import lock and won't let go of it until this module returns. All other |
| 26 | # threads attempting an import hang for the duration. So we have to spawn |
| 27 | # a thread to run the test and return to regrtest.py right away, else the |
| 28 | # test can't make progress. |
| 29 | # |
| 30 | # One miserable consequence: This test can't wait to make sure all the |
| 31 | # threads complete! |
| 32 | # |
| 33 | # Another: If this test fails, the output may show up while running |
| 34 | # some other test. |
| 35 | # |
| 36 | # Another: If you run this test directly, the OS will probably kill |
| 37 | # all the threads right away, because the program exits immediately |
| 38 | # after spawning a thread to run the real test. |
| 39 | # |
| 40 | # Another: If this test ever does fail and you attempt to run it by |
| 41 | # itself via regrtest, the same applies: regrtest will get out so fast |
| 42 | # the OS will kill all the threads here. |
| 43 | |
| 44 | def run_the_test(): |
| 45 | global N, done |
| 46 | done.acquire() |
| 47 | for N in [1, 2, 3, 4, 20, 4, 3, 2]: |
| 48 | for i in range(N): |
| 49 | thread.start_new_thread(task, ()) |
| 50 | done.acquire() |
| 51 | |
| 52 | thread.start_new_thread(run_the_test, ()) |