原型如下:
system(command)
实际是调用系统内置的命令行程序来执行系统命令, 所以在命令结束之后会将控制权返回给Python进程。
如果返回0,说明执行成功,否则表示失败
共有8个类似函数:execl
, execle
, execlp
, execv
, execve
, execvp
, execvpe
exec函数执行完命令之后,将会接管Python进程, 而不会将控制权返回给Python进程。也就是说,Python进程会在调用exec函数之后终止。新生成的进程将会替换主进程。这些函数没有返回值,如果发生错误,将会触发OSError异常
Python使用全局解释器锁(GIL)来保证解释其中仅有一个线程,并在各个线程之间切换。当GIL可用的时候,处于就绪状态的线程在获取GIL之后就可以运行了。线程将在指定的间隔时间内运行,时间到之后重新进入就绪队列排队。当然,特定的事件可能导致中断。
Python提供了两种不同的方式:
多线程的协调:
threading模块中提供了数据同步的方法。Queue模块中,有一个同步的FIFO队列,特别适于多线程的同步。
thread模块
常用方法:
start_new_thread
生成新线程,返回标识符的值exit
退出,触发一个 SystemExit 异常get_ident
获取标识符allocate_lock
加锁interrupt_main
在主线程中触发一个KeyboardInterrupt异常stack_size
返回堆栈大小示例程序:
import _thread
import time
def hello(index):
for v in range(5):
time.sleep(2)
print("线程", v, index)
def test():
_thread.start_new_thread(hello, (1,))
_thread.start_new_thread(hello, (2,))
test()
time.sleep(15)
threading.thread类
常用方法:
start
允许进程实例run
实现自己的线程时需要重载此方法join
阻塞主线程,开始执行此线程getName
返回线程名setName
设置线程名isAlive
查看线程是否运行isDaemon
查看线程是否在后台运行setDaemon
设置线程后台运行使用示例:
import threading
def z():
print("线程名:" + threading.current_thread().getName())
t1 = threading.Thread(target=z, name="my")
t1.start()
自定义Thread(继承自threading.thread):
import threading
import time
import random
class MyThread(threading.Thread):
def __init__(self, name):
threading.Thread.__init__(self, name=name)
def run(self):
for i in range(5):
time.sleep(random.randint(1, 10))
print("我是", self.name, "线程,第", i + 1, "次循环")
a = MyThread("A")
# a.setDaemon(True)
a.start()
b = MyThread("B")
# b.setDaemon(True)
b.start()
a.join() # 加入join之后,先运行子线程,然后再执行之后的主线程代码!
b.join()
print("主线程退出,end!")
线程状态转移:就绪、运行、休眠、终止
线程中的局部变量:
import threading
import random
import time
class ThreadLocal():
def __init__(self):
self.local = threading.local()
def run(self):
time.sleep(random.random())
self.local.number = []
for i in range(10):
self.local.number.append(random.choice(range(10)))
print(threading.currentThread(), self.local.number)
ThreadLocal = ThreadLocal()
threads = []
for i in range(5):
t = threading.Thread(target = ThreadLocal.run)
t.start()
threads.append(t)
for i in range(5):
threads[i].join()
另一种:
import threading
import random
import time
class ThreadLocal(threading.Thread):
def __init__(self, name):
threading.Thread.__init__(self)
self.local = threading.local()
def run(self):
time.sleep(random.random())
self.local.number = []
for i in range(10):
self.local.number.append(random.choice(range(10)))
print(threading.currentThread(), self.local.number)
threads = []
for i in range(5):
t = ThreadLocal(str(i))
t.start()
threads.append(t)
for i in range(5):
threads[i].join()
4.1 临界资源与临界区
4.2 锁机制
Lock:
import _thread
import time
mylock = _thread.allocate_lock() # Allocate a lock
num = 0 # Shared resource
def add_num(name):
global num
while True:
mylock.acquire() # Get the lock
# Do something to the shared resource
print('Thread %s locked! num=%s' % (name, str(num)))
if num >= 5:
print('Thread %s released! num=%s' % (name, str(num)))
mylock.release()
num = 0
_thread.exit_thread()
num += 1
print('Thread %s released! num=%s' % (name, str(num)))
mylock.release() # Release the lock.
def test():
_thread.start_new_thread(add_num, ('A',))
_thread.start_new_thread(add_num, ('B',))
if __name__ == '__main__':
test()
time.sleep(5)
RLock:
import threading
mylock = threading.RLock()
num = 0
class myThread(threading.Thread):
def __init__(self, name):
threading.Thread.__init__(self)
self.t_name = name
def run(self):
global num # 声明为全局变量
while True:
mylock.acquire()
print('\nThread(%s) locked, Number: %d' % (self.t_name, num))
if num >= 4:
mylock.release()
print('\nThread(%s) released, Number: %d' % (self.t_name, num))
break
num += 1
print('\nThread(%s) released, Number: %d' % (self.t_name, num))
mylock.release()
def test():
thread1 = myThread('A')
thread2 = myThread('B')
thread1.start()
thread2.start()
if __name__ == '__main__':
test()
4.3 条件变量
4.4 信号量
4.5 同步队列
import threading
import queue # Python3中将Queue改为了queue,千万注意!
import time
import random
class Worker(threading.Thread):
def __init__(self, index, queue):
threading.Thread.__init__(self)
self.index = index
self.queue = queue
def run(self):
while 1:
time.sleep(random.random())
item = self.queue.get()
if item is None:
break
print("index", self.index, "task", item, "finished")
self.queue.task_done()
q = queue.Queue()
for i in range(2):
Worker(i, q).start()
for i in range(10):
q.put(i)
for i in range(2):
q.put(None)