python thread start_Python threading.thread.start()不会将控制权返回给主线程

I'm trying to a program that executes a piece of code in such a way that the user can stop its execution at any time without stopping the main program. I thought I could do this using threading.Thread, but then I ran the following code in IDLE (Python 3.3):

from threading import *

import math

def f():

eval("math.factorial(1000000000)")

t = Thread(target = f)

t.start()

The last line doesn't return: I eventually restarted the shell. Is this a consequence of the Global Interpreter Lock, or am I doing something wrong? I didn't see anything specific to this problem in the threading documentation (http://docs.python.org/3/library/threading.html)

I tried to do the same thing using a process:

from multiprocessing import *

import math

def f():

eval("math.factorial(1000000000)")

p = Process(target = f)

p.start()

p.is_alive()

The last line returns False, even though I ran it only a few seconds after I started the process! Based on my processor usage, I am forced to conclude that the process never started in the first place. Can somebody please explain what I am doing wrong here?

解决方案Thread.start() never returns! Could this have something to do with the C implementation of the math library?

As @eryksun pointed out in the comment: math.factorial() is implemented as a C function that doesn't release GIL so no other Python code may run until it returns.

Note: multiprocessing version should work as is: each Python process has its own GIL.

factorial(1000000000) has hundreds millions of digits. Try import time; time.sleep(10) as dummy calculation instead.

If you have issues with multithreaded code in IDLE then try the same code from the command line, to make sure that the error persists.

If p.is_alive() returns False after p.start() is already called then it might mean that there is an error in f() function e.g., MemoryError.

On my machine, p.is_alive() returns True and one of cpus is at 100% if I paste your code from the question into Python shell.

Unrelated: remove wildcard imports such as from multiprocessing import *. They may shadow other names in your code so that you can't be sure what a given name means e.g., threading could define eval function (it doesn't but it could) with a similar but different semantics that might break your code silently.

I want my program to be able to handle ridiculous inputs from the user gracefully

If you pass user input directly to eval() then the user can do anything.

Is there any way to get a process to print, say, an error message without constructing a pipe or other similar structure?

It is an ordinary Python code:

print(message) # works

The difference is that if several processes run print() then the output might be garbled. You could use a lock to synchronize print() calls.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值