在学习python对应线程、进程模块之前先了解一下线程、进程概念。
进程:就是一块包含了某些资源的内存区域,操作系统利用进程把他的工作划分为一些功能单元。进程中包含一个或多个线程,用于自己私有的虚拟地址空间。该空间仅能被他所包含的线程访问。当操作系统创建一个主线程后,该进程会自动申请一个名为主线程或首要线程的线程。简单来说,进程就是指正在运行的程序。也就是说,当一个程序进入内存运行,就变成了一个进程。
线程:是一个进程中的执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个程序也可以称为多线程程序。线程在切换时负荷小,所以线程也被称为轻负荷进程。
总之:一个程序运行后,至少有一个进程,一个进程中包含一个或者多个线程。
多线程就是一个程序中有多个线程在同时执行。
线程和进程的区别:
- 一个进程至少有一个线程,线程的划分尺度小于进程。
- 进程应有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。 线程在执行过程中,每个独立的线程有一个程序运行的入口,顺序执行序列,程序运行的出口,但是线程不能独立运行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
线程使用的场合
线程通常用于在一个程序中需要同时完成多个任务的情况,我们可以将每个任务定义为一个线程,使得他们一同工作。
并发原理
多个线程或进程“同时”运行只是我们感官上的一种表现,事实上进程和线程是并发运行的。OS的线程调度机制将时间划分为很多时间片段(时间片),尽可能的均匀分配给正在运行的程序。获取到时间片的线程或进程才会被执行,其他的则处于等待状态,而CPU则在这些进程和线程上来回切换运行。
原文链接:https://blog.csdn.net/he_zhen_/article/details/87456727
python中使用threading模块进行线程处理
1 #!/usr/bin/python3 2 3 import threading 4 import time 5 6 exitFlag = 0 7 class myThread(threading.Thread): 8 def __init__(self,threadID,name,delay): 9 threading.Thread.__init__(self) 10 self.name = name 11 self.delay = delay 12 13 def run(self): 14 print("开启线程:"+self.name) 15 print_time(self.name,self.delay,5) 16 print("退出线程:"+self.name) 17 18 19 20 def print_time(threadName,delay,counter): 21 while counter: 22 if exitFlag: 23 threadName.exit() 24 time.sleep(delay) 25 print("%s:%s" %(threadName,time.ctime(time.time()))) 26 counter -= 1 27 28 #创建新线程 29 thread1 = myThread(1,"Thread-1",1) 30 thread2 = myThread(2,"Thread-2",2) 31 32 #开启新线程 33 thread1.start() #启动线程活动 34 thread2.start() 35 thread1.join() #等待至线程中止 36 thread2.join() 37 print("退出主线程")
线程同步
如果多个线程共同对某个数据修改,则可能出现不可预料的结果,为了保证数据的正确性,需要对多个线程进行同步。
使用 Thread 对象的 Lock 和 Rlock 可以实现简单的线程同步,这两个对象都有 acquire 方法和 release 方法,对于那些需要每次只允许一个线程操作的数据,可以将其操作放到 acquire 和 release 方法之间。如下:
多线程的优势在于可以同时运行多个任务(至少感觉起来是这样)。但是当线程需要共享数据时,可能存在数据不同步的问题。
1 #!/usr/bin/python3 2 3 import threading 4 import time 5 6 exitFlag = 0 7 class myThread(threading.Thread): 8 def __init__(self,threadID,name,delay): 9 threading.Thread.__init__(self) 10 self.name = name 11 self.delay = delay 12 13 def run(self): 14 print("开启线程:"+self.name) 15 threadLock.acquire() 16 print_time(self.name,self.delay,5) 17 threadLock.release() 18 print("退出线程:"+self.name) 19 20 21 22 def print_time(threadName,delay,counter): 23 while counter: 24 if exitFlag: 25 threadName.exit() 26 time.sleep(delay) 27 print("%s:%s" %(threadName,time.ctime(time.time()))) 28 counter -= 1 29 30 threadLock = threading.Lock() 31 threads = [] 32 33 #创建新线程 34 thread1 = myThread(1,"Thread-1",1) 35 thread2 = myThread(2,"Thread-2",2) 36 37 #开启新线程 38 thread1.start() #启动线程活动 39 thread2.start() 40 41 #添加线程到线程列表 42 threads.append(thread1) 43 threads.append(thread2) 44 45 for t in threads: 46 t.join() #等待至线程中止 47 print("退出主线程")
线程优先级队列( Queue)
Python 的 Queue 模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列 PriorityQueue。
这些队列都实现了锁原语,能够在多线程中直接使用,可以使用队列来实现线程间的同步。
Queue 模块中的常用方法:
- Queue.qsize() 返回队列的大小
- Queue.empty() 如果队列为空,返回True,反之False
- Queue.full() 如果队列满了,返回True,反之False
- Queue.full 与 maxsize 大小对应
- Queue.get([block[, timeout]])获取队列,timeout等待时间
- Queue.get_nowait() 相当Queue.get(False)
- Queue.put(item) 写入队列,timeout等待时间
- Queue.put_nowait(item) 相当Queue.put(item, False)
- Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号
- Queue.join() 实际上意味着等到队列为空,再执行别的操作
1 import queue 2 import threading 3 import time 4 5 exitFlag = 0 6 7 class myThread (threading.Thread): 8 def __init__(self, threadID, name, q): 9 threading.Thread.__init__(self) 10 self.threadID = threadID 11 self.name = name 12 self.q = q 13 def run(self): 14 print ("开启线程:" + self.name) 15 process_data(self.name, self.q) 16 print ("退出线程:" + self.name) 17 18 def process_data(threadName, q): 19 while not exitFlag: 20 queueLock.acquire() 21 if not q.empty(): 22 data = q.get() 23 queueLock.release() 24 print ("%s processing %s" % (threadName, data)) 25 else: 26 queueLock.release() 27 time.sleep(1) 28 29 threadList = ["Thread-1", "Thread-2", "Thread-3"] 30 nameList = ["One", "Two", "Three", "Four", "Five"] 31 queueLock = threading.Lock() 32 workQueue = queue.Queue(10) 33 threads = [] 34 threadID = 1 35 36 # 创建新线程 37 for tName in threadList: 38 thread = myThread(threadID, tName, workQueue) 39 thread.start() 40 threads.append(thread) 41 threadID += 1 42 43 # 填充队列 44 queueLock.acquire() 45 for word in nameList: 46 workQueue.put(word) 47 queueLock.release() 48 49 # 等待队列清空 50 while not workQueue.empty(): 51 pass 52 53 # 通知线程是时候退出 54 exitFlag = 1 55 56 # 等待所有线程完成 57 for t in threads: 58 t.join() 59 print ("退出主线程")
python中进程可以使用process模块
1 #!/usr/bin/env python 2 #-*-coding:utf-8-*- 3 4 from multiprocessing import Process 5 import os 6 import time as t 7 8 def f(): 9 t.sleep(2) 10 print("这是进程") 11 12 if __name__ == '__main__': 13 p=Process(target=f) 14 p.start() 15 print('父进程PID:{0}'.format(os.getppid())) 16 print('子进程PID:{0}'.format(os.getpid()))