刚开始学习多进程、多线程,看了教程和借阅的书本上的知识。先百度了下它们两者的区别,发现了这个讲解挺清楚的网站:
http://blog.csdn.net/hairetz/article/details/4281931
我基本上都是通过代码示例来进行对它们的学习,通过运行代码、改动代码来查看运行结果。然后对各个模块有的类、对象、函数进行了解。所以我就会通过代码示例来总结我的学习
进程
进程就是程序在计算机上的一次执行活动
int main()
{
print("pid is %d/n",getpid());
return 0;
}
进入main函数,这就是一个进程,pid会被打印出来,该函数就是该进程的唯一一次执行。return后,该进程也会退出。
多进程
创建多进程,要用到fork()函数
import os
print('Process (%s) start...' % os.getpid())
pid = os.fork()
if pid == 0:
print('I am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid()))
else:
print('I (%s) just created a child process (%s).' % (os.getpid(), pid))
运行结果如下:
Process (876) start...
I (876) just created a child process (877).
I am child process (877) and my parent is 876.
、、、、、、
multiprocessing模块提供一个类来代表进程对象
from multiprocessing import Process
import os
def run_proc(name):
print('Run child process %s (%s)...' % (name, os.getpid()))
if __name__=='__main__':
print('Parent process %s.' % os.getpid())
p = Process(target=run_proc, args=('test',))
print('Child process will start.')
p.start()
p.join()
print('Child process end.')
执行结果如下:
Parent process 928.
Process will start.
Run child process test (929)...
Process end.
其中,start()是自动调用run()方法,启动进程。join()等待进程结束或超时返回
、、、、、、
进程间的通信要用到Queue、Pipes等多种方式来交换数据
创建两个子进程
from multiprocessing import Process, Queue
import os, time, random
**写数据进程执行的代码:**
def write(q):
print('Process to write: %s' % os.getpid())
for value in ['A', 'B', 'C']:
print('Put %s to queue...' % value)
q.put(value)
time.sleep(random.random())
**读数据进程执行的代码:**
def read(q):
print('Process to read: %s' % os.getpid())
while True:
value = q.get(True)
print('Get %s from queue.' % value)
if __name__=='__main__':
**父进程创建Queue,并传给各个子进程:**
q = Queue()
pw = Process(target=write, args=(q,))
pr = Process(target=read, args=(q,))
pw.start()
pr.start()
pw.join()
pr.terminate()
运行结果如下:
Process to write: 50563
Put A to queue...
Process to read: 50564
Get A from queue.
Put B to queue...
Get B from queue.
Put C to queue...
Get C from queue.
多线程
线程就是把一个进程分为很多片,每一片都可以是一个独立的流程
多线程编程中的threading模块
通过代码块展示该模块方法的用法
>>> import threading
>>> threading.stack_size() #查看当前线程栈的大小
0
>>> threading.stack_size(64*1024) #设置当前线程栈的大小
0
>>> threading.stack_size()
65536
>>> threading.active_count() #返回当前处于alive状态的所有Thread对象列表
2
>>> threading.current_thread() #返回当前Thread对象
<_MainThread(MainThread, started 3768)>
>>> threading.enumerate() #返回当前处于alive状态的所有Thread对象列表
[<_MainThread(MainThread, started 3768)>, <Thread(SockThread, started daemon 8916)>]
、、、
多线程中的Thread对象
通过代码能够了解到一些Thread对象的成员的作用
import threading
import time
def func1(x, y):
for i in range(x, y):
print(i)
time.sleep(10)
t1=threading.Thread(target = func1, args = (15, 20))
t1.start()
t1.join(5)
t2=threading.Thread(target = func1, args = (5, 10))
t2.start()
将join(5)注释前后运行此程序会有不一样的结果,为了更细致的了解join()函数的作用,百度到了一个很详细的网址,讲述了join()函数带参数和不带参数的用法区别
http://www.gimoo.net/t/1409/54102124374f3.html
、、、
Thread对象的isAlive函数示例
若线程运行结束,此时调用isAive返回值为false;反之,则为True
import threading
import time
def func1(x, y):
for i in range(x, y):
print(i)
#time.sleep(10)
t1=threading.Thread(target = func1, args = (15, 20))
t1.start()
t1.join(5)
t2=threading.Thread(target = func1, args = (5, 10))
t2.start()
t2.join()
print('t1:',t1.isAlive())
print('t2:',t2.isAlive())
通过此代码可以发现,改变join()函数内参数的值会改变线程的运行状态,从而加强了我对join()函数和isAlive函数的理解
、、、
线程的同步技术的Lock和Rlock对象
下边的代码演示了使用Lock和Rlock对象实现线程同步的思路和步骤
import threading
import time
class mythread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
global x #声明一个全局变量
lock.acquire() #上锁,acquire()和release()之间的语句只能有一个线程进入,其余的线程在acquire()处等待
for i in range(3):
x=x+i
time.sleep(2)
print(x)
lock.release() #解锁
lock=threading.RLock()
t1=[]
for i in range(10):
t=mythread()
t1.append(t) #创建10个线程,并把它们放在一个列表里
x=0
for i in t1:
i.start() #开启列表中的所有线程
acquire()方法能够将unlocked状态修改成locked状态并立即返回
release()方法locked状态修改成unlocked状态并立即返回
通过对这两个函数注释前后运行结果的分析能够让我了解这两个函数的作用
还有一些实现线程同步的对象,比如:Condition对象、Queue对象、Event对象