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)
相关文章推荐
- Python进阶 - GUI程序设计(tkinter)
- 二分法查找的Python实现
- python实现部分实例
- python随笔2: PIL参考手册翻译(0-3)
- OpenCV3.0.0 rc1与Python2.7.5配置
- 使用IPython探索和可视化数据
- python list
- python IDE
- python
- 【4】Python对象
- 用python实现git blob对象的创建和查询
- python : defaultdict
- [Python学习] 专题六.局部变量、全局变量global、导入模块变量
- python入门之(语法介绍)
- 爬取淘宝MM图片
- 使用pip来安装和管理第三方Python包(library)
- 相关Python分割操作
- python编程之if/for/while语句
- python入门之(元组、文件)
- python(四)字典,集合,可变与不可变对象(下)