您的位置:首页 > 编程语言 > Python开发

Python进阶 - 进程与线程

2015-09-27 22:31 911 查看

1 Python下的进程编程

1.1 创建进程

system函数

原型如下:

system(command)


实际是调用系统内置的命令行程序来执行系统命令, 所以在命令结束之后会将控制权返回给Python进程。

如果返回0,说明执行成功,否则表示失败

exec家族

共有8个类似函数:
execl
,
execle
,
execlp
,
execv
,
execve
,
execvp
,
execvpe


exec函数执行完命令之后,将会接管Python进程, 而不会将控制权返回给Python进程。也就是说,Python进程会在调用exec函数之后终止。新生成的进程将会替换主进程。这些函数没有返回值,如果发生错误,将会触发OSError异常

1.2 终止进程

sys.exit() 退出之前执行清理操作,更加优雅

sys.abort() 直接发出终止信号,在exit不能终止程序的时候用这个。

2 多线程编程

2.1 Python多线程简介

Python使用全局解释器锁(GIL)来保证解释其中仅有一个线程,并在各个线程之间切换。当GIL可用的时候,处于就绪状态的线程在获取GIL之后就可以运行了。线程将在指定的间隔时间内运行,时间到之后重新进入就绪队列排队。当然,特定的事件可能导致中断。

Python提供了两种不同的方式:

thread 低级的线程处理模块,仅提供最少的线程处理功能,在实际的代码中最好不要使用该模块

threading 高级的线程处理模块,基于thread模块,部分思想来自于Java的thread类

多线程的协调:

threading模块中提供了数据同步的方法。Queue模块中,有一个同步的FIFO队列,特别适于多线程的同步。

2.2 生成和终止线程

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!")


3 管理线程

线程状态转移:就绪、运行、休眠、终止

线程中的局部变量

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 线程之间的同步

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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: