主线程是什么:~~~就是我们的main函数,其实main函数就是我们的主线程的入口。程序运行的时候,系统会将我们的代码加载到内存当中,进入主线程,运行代码,程序就呼啦呼啦跑起来了。
主线程,父线程,子线程的关系
这里必须先说明一点,主线程和父线程。
主线程:可以认为,主线程是程序的一条主线,一旦主线程结束,程序就结束了。其他所有线程都GAME OVER了。简单理解,主线程就是游戏中的主线任务,主线任务做完了,程序就通关,结束了。
父进程:一个进程中可以有很多的线程,CreateTread()函数中就有一个参数可以指定创建线程的入口,简单的说,就是可以自定义一个线程启动入口,这个时候可以新创建一个线程,而在这个线程中可以在此掉用CreateTread()函数来创建别的线程。这样的话,线程之间就可以层层嵌套,就和C++中的父类子类一回事,如果还无法理解,回家看C++继承。。。。~!!!
但是这里要说明一点,主线程好像不能成为任何线程的父线程,这个下面会说明的。。。。。
子线程:父线程的儿子。~!!!!!!!!、
当父线程消亡的时候,子线程是不会消亡的,是会继续执行到结束的。。。。。。。~!!!!!这个很重要。。。。。 因为线程只有在windows系统的R3层上看来是有嵌套父子关系的,而在内核当中,他们都是独立的内核对象。。。。。。 重点,都是独立的。所以,当父线程消亡的时候,子线程其实是可以继续执行的。
但是~!!当主线程消亡的时候,所有线程都得死。。。。都得死。。都得死~~!!!!!重要的事情说三遍。所以我觉得,主线程是不能看作任何线程的父线程的,这里就不满足父子线程的特性啊。。。。
一、使用threading模块创建线程
1、三种线程创建方式
(1)传入一个函数
- #!/usr/bin/python
- #-*-coding:utf-8-*-
- import threading
- #用于线程执行的函数
- def counter(n):
- cnt = 0;
- for i in xrange(n):
- for j in xrange(i):
- cnt += j;
- print cnt;
- if __name__ == '__main__':
- #初始化一个线程对象,传入函数counter,及其参数1000
- th = threading.Thread(target=counter, args=(1000,));
- #启动线程
- th.start();
- #主线程阻塞等待子线程结束
- th.join();
(2)传入一个可调用的对象
- #!/usr/bin/python
- #-*-coding:utf-8-*-
- import threading
- #可调用的类
- class Callable(object):
- def __init__(self, func, args):
- self.func = func;
- self.args = args;
- def __call__(self):
- apply(self.func, self.args);
- #用于线程执行的函数
- def counter(n):
- cnt = 0;
- for i in xrange(n):
- for j in xrange(i):
- cnt += j;
- print cnt;
- if __name__ == '__main__':
- #初始化一个线程对象,传入可调用的Callable对象,并用函数counter及其参数1000初始化这个对象
- th = threading.Thread(target=Callable(counter, (1000,)));
- #启动线程
- th.start();
- #主线程阻塞等待子线程结束
- th.join();
(3)继承Thread类
- #!/usr/bin/python
- #-*-coding:utf-8-*-
- import threading, time, random
- def counter():
- cnt = 0;
- for i in xrange(10000):
- for j in xrange(i):
- cnt += j;
- class SubThread(threading.Thread):
- def __init__(self, name):
- threading.Thread.__init__(self, name=name);
- def run(self):
- i = 0;
- while i < 4:
- print self.name,'counting...\n';
- counter();
- print self.name,'finish\n';
- i += 1;
- if __name__ == '__main__':
- th = SubThread('thread-1');
- th.start();
- th.join();
- print 'all done';
2、python多线程的限制
二、使用multiprocessing创建进程
1、三种创建方式
在Python中创建进程有两种方式,第一种是:
[python] view plain copy
- from multiprocessing import Process
- import time
- def test():
- while True:
- print('---test---')
- time.sleep(1)
- if __name__ == '__main__':
- p=Process(target=test)
- p.start()
- while True:
- print('---main---')
- time.sleep(1)
第二种方式是:
通过子类继承Process类,子类中必须有run方法,里面实现进程功能,创建子类对象之后,调用对象的start方法。
进程池,就是实现已经创建好的进程
- from multiprocessing import Process
- import time
- class MyNewProcess(Process):
- def run(self):
- while True:
- print('---1---')
- time.sleep(1)
- if __name__=='__mian__':
- p = MyNewProcess()
- # 调用p.start()方法,p会先去父类中寻找start(),然后在Process的start方法中调用run方法
- p.start()
- while True:
- print('---Main---')
- time.sleep(1)
Pool方法就是创建了一个进程池,3表示创建进程数,通过pool.apply_async( )将子进程添加到进程池中,pool.close( )表示关闭进程池,一定要添加join函数,否则主进程直接断了,不能看到子进程的结果。
- # 进程池
- from multiprocessing import Pool
- import os
- import random
- import time
- def worker(num):
- for i in range(5):
- print('===pid=%d==num=%d='%(os.getpid(),num))
- time.sleep(1)
- # 3表示进程池中最多有三个进程一起执行
- pool=Pool(3)
- for i in range(10):
- print('---%d---'%i)
- # 向进程中添加任务
- # 注意:如果添加的任务数量超过了进程池中进程的个数的话,那么就不会接着往进程池中添加,如果还没有执行的话,他会等待前面的进程结束,然后在往
- # 进程池中添加新进程
- pool.apply_async(worker,(i,))
- pool.close() # 关闭进程池
- pool.join() # 主进程在这里等待,只有子进程全部结束之后,在会开启主线程