线程: 有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。是一串指令的集合。
线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指运行中的程序的调度单位。
在单个程序中同时运行多个线程完成不同的工作,称为多线程

进程: qq 要以一个整体的形式暴露给操作系统管理,里面包含对各种资源的调用,内存的管理,网络接口的调用等。。。
对各种资源管理的集合 就可以成为进程。

进程 要操作cpu , 必须要先创建一个线程,
all the threads in a process have the same view of the memory
所有在同一个进程里的线程是共享同一块内存空间的


进程与线程的区别?

Threads share the address space of the process that created it; processes have their own address space.
线程共享内存空间,进程的内存是独立的
Threads have direct access to the data segment of its process; processes have their own copy of the data segment of the parent process. Threads can directly communicate with other threads of its process; processes must use interprocess communication to communicate with sibling processes.
同一个进程的线程之间可以直接交流,两个进程想通信,必须通过一个中间代理来实现 New threads are easily created; new processes require duplication of the parent process.
创建新线程很简单, 创建新进程需要对其父进程进行一次克隆 Threads can exercise considerable control over threads of the same process; processes can only exercise control over child processes.
一个线程可以控制和操作同一进程里的其他线程,但是进程只能操作子进程 Changes to the main thread (cancellation, priority change, etc.) may affect the behavior of the other threads of the process; changes to the parent process does not affect child processes.

threading模块

import time
import threading def run(n):
print('task.....',n)
time.sleep(2) # run("t1")
# run("t2") #普通写法
t1 = threading.Thread(target=run,args=("t1",))
t2 = threading.Thread(target=run,args=("t2",))
t1.start()
t2.start()
import time
import threading
#类写法
class MyThread(threading.Thread):
def __init__(self,n,sleep_time):
super(MyThread, self).__init__()
self.n = n
self.sleep_time = sleep_time
def run(self):
print("task", self.n)
time.sleep(self.sleep_time)
print("task done") t1 = MyThread("t1",2)
t2 = MyThread("t2",4) t1.start()
t2.start()
import threading
import time def run(n):
print("task ",n )
time.sleep(2)
print("task done",n) start_time = time.time()
t_objs = [] #存线程实例
for i in range(50):
t = threading.Thread(target=run,args=("t-%s" %i ,))
t.start()
t_objs.append(t) #为了不阻塞后面线程的启动,不在这里join,先放到一个列表里 for t in t_objs: #循环线程实例列表,等待所有线程执行完毕
t.join() print(t_objs)
print("----------all threads has finished...")
print("cost:",time.time() - start_time)
Daemon:守护进程,即主进程一结束,守护进程也就结束
import threading
import time def run(n):
print("task ",n )
time.sleep(2)
print("task done",n,threading.current_thread()) start_time = time.time()
t_objs = [] #存线程实例
for i in range(50):
t = threading.Thread(target=run,args=("t-%s" %i ,))
t.setDaemon(True) #把当前线程设置为守护线程
t.start()
t_objs.append(t) #为了不阻塞后面线程的启动,不在这里join,先放到一个列表里 # for t in t_objs: #循环线程实例列表,等待所有线程执行完毕
# t.join() # time.sleep(2)
print("----------all threads has finished...",threading.current_thread(),threading.active_count())
print("cost:",time.time() - start_time)

全局锁

import threading
import time def run(n):
lock.acquire()#获得锁,除非释放掉锁,否则其他线程就不能再次获得,2.7中试,3.0以后不需要了
global num
num +=1
# time.sleep(1)
lock.release()#释放锁,其他线程可以获得了 lock = threading.Lock()
num = 0
t_objs = [] #存线程实例
for i in range(50):
t = threading.Thread(target=run,args=("t-%s" %i ,))
t.start()
t_objs.append(t) #为了不阻塞后面线程的启动,不在这里join,先放到一个列表里 for t in t_objs: #循环线程实例列表,等待所有线程执行完毕
t.join() print("----------all threads has finished...",threading.current_thread(),threading.active_count())
print("num:",num)


信号量:即同时可以获得多个锁

import threading
import time def run(n):
semaphore.acquire()#信号量获取
time.sleep(1)
print("run the thread :%s\n" %n)
semaphore.release()#信号量释放 if __name__ == "__main__":
semaphore = threading.BoundedSemaphore(5) #设置信号量,即绑定信号量可以同时拥有的锁的数量
for i in range(22):
t = threading.Thread(target = run,args = (i,))
t.start() while threading.active_count() !=1 :#当前活跃的线程数
pass else:
print("______-all threads done______")

Event:

event = threading.Event()#生成event对象
event.set()#设置event标志位
event.clear()#清除event标志位
event.is_set():#判断event是否设置了标志位

红绿灯例子:

import time
import threading event = threading.Event()#生成event对象
def lighter():
event.set()#设置event标志位
count = 0
while True:
if count >5 and count <10:
event.clear()#清除event标志位
print("\033[41;1m红灯亮....\033[0m")
elif count > 10:
event.set()
print("\033[42;1m绿灯亮了....\033[0m")
count = 0
else:
print("\033[42;1m绿灯亮着\033[0m")
time.sleep(1)
count +=1 def car(n):
while True:
if event.is_set():#判断event是否设置了标志位
print('\033[34;2m[%s] running..... \033[0m'%n)
time.sleep(0.5)
else:
print('[%s] stoping.....'%n)
event.wait()
print('路灯亮了[%s]开跑'%n) light = threading.Thread(target=lighter,)
light.start() car1 = threading.Thread(target=car,args=('宝马',))
car1.start() car2 = threading.Thread(target=car,args=('大奔驰',))
car2.start() car3 = threading.Thread(target=car,args=('玛莎拉蒂',))
car3.start()


多进程:

和线程用法基本一致,我threading.Thread换成multiprocessing.Process

import time,threading
import multiprocessing def thread_run():
print(threading.get_ident()) def run(name):
time.sleep(2)
print("hellp",name)
t = threading.Thread(target=thread_run,)
t.start() if __name__ =="__main__":
for i in range (10):
p = multiprocessing.Process(target=run,args=("bob %s"%i,))#与线程用法基本机制
p.start()

数据在不同进程间进行交换

from multiprocessing import Process,Queue

def f(qq):
qq.put([42,None,156161]) if __name__ =="__main__":
q =Queue()#可以在不同进程间交互使用
p = Process(target=f,args=(q,))#把q作为参数传入
p.start()
print(q.get())#父进程可以得到子进程中修改过的数据
p.join()

进程池

Note:  from multiprocessing import Process, Pool,freeze_support

  pool = Pool(processes=5) #允许进程池同时放入5个进程
  pool.apply_async(func=Foo, args=(i,), callback=Bar) #callback=回调,父进程操作
#pool.apply(func=Foo, args=(i,)) #串行
#pool.apply_async(func=Foo, args=(i,)) #并行
from  multiprocessing import Process, Pool,freeze_support
import time
import os def Foo(i):
time.sleep(2)
print("in process",os.getpid())
return i + 100 def Bar(arg):
print('-->exec done:', arg,os.getpid()) if __name__ == '__main__':#window必须加这一句
#freeze_support()
pool = Pool(processes=5) #允许进程池同时放入5个进程
print("主进程",os.getpid())
for i in range(10):
pool.apply_async(func=Foo, args=(i,), callback=Bar) #callback=回调
#pool.apply(func=Foo, args=(i,)) #串行
#pool.apply_async(func=Foo, args=(i,)) #并行
print('end')
pool.close()
pool.join() #进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。.join()

进程锁:变串行了

from multiprocessing import Process, Lock

def f(l, i):
#l.acquire()
print('hello world', i)
#l.release() if __name__ == '__main__':
lock = Lock() for num in range(100):
Process(target=f, args=(lock, num)).start()

Manager:进程间交换数据

from multiprocessing import Process, Manager
import os
def f(d, l):
d[os.getpid()] =os.getpid()
l.append(os.getpid())
print(l) if __name__ == '__main__':
with Manager() as manager:
d = manager.dict() #{} #生成一个字典,可在多个进程间共享和传递 l = manager.list(range(5))#生成一个列表,可在多个进程间共享和传递
p_list = []
for i in range(10):
p = Process(target=f, args=(d, l))
p.start()
p_list.append(p)
for res in p_list: #等待结果
res.join() print(d)
print(l)

Pipe:生成两个可以交互数据的进程

parent_conn, child_conn = Pipe()#生成两个可以交换数据的进程
from multiprocessing import Process, Pipe

def f(conn):
conn.send([42, None, 'hello from child'])
conn.send([42, None, 'hello from child2'])
print("from parent:",conn.recv())
conn.close() if __name__ == '__main__':
parent_conn, child_conn = Pipe()#生成两个可以交换数据的进程
p = Process(target=f, args=(child_conn,))
p.start()
print(parent_conn.recv()) # prints "[42, None, 'hello']"
print(parent_conn.recv()) # prints "[42, None, 'hello']"
parent_conn.send("可好") # prints "[42, None, 'hello']"
p.join()

												

人生苦短之我用Python篇(线程/进程、threading模块:全局解释器锁gil/信号量/Event、)的更多相关文章

  1. 21.线程,全局解释器锁(GIL)

    import time from threading import Thread from multiprocessing import Process #计数的方式消耗系统资源 def two_hu ...

  2. python 什么是全局解释器锁GIL

    什么是全局解释器锁GIL Python代码的执行由Python 虚拟机(也叫解释器主循环,CPython版本)来控制,Python 在设计之初就考虑到要在解释器的主循环中,同时只有一个线程在执行,即在 ...

  3. {Python之线程} 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Threading模块 九 锁 十 信号量 十一 事件Event 十二 条件Condition(了解) 十三 定时器

    Python之线程 线程 本节目录 一 背景知识 二 线程与进程的关系 三 线程的特点 四 线程的实际应用场景 五 内存中的线程 六 用户级线程和内核级线程(了解) 七 python与线程 八 Thr ...

  4. python 线程队列、线程池、全局解释器锁GIL

    一.线程队列 队列特性:取一个值少一个,只能取一次,没有值的时候会阻塞,队列满了,也会阻塞 queue队列 :使用import queue,用法与进程Queue一样 queue is especial ...

  5. <python的线程与threading模块>

    <python的线程与threading模块> 一 线程的两种调用方式 threading 模块建立在thread 模块之上.thread模块以低级.原始的方式来处理和控制线程,而thre ...

  6. 全局解释器锁GIL & 线程锁

    1.GIL锁(Global Interpreter Lock) Python代码的执行由Python虚拟机(也叫解释器主循环)来控制.Python在设计之初就考虑到要在主循环中,同时只有一个线程在执行 ...

  7. Python如何规避全局解释器锁(GIL)带来的限制

    编程语言分类概念介绍(编译型语言.解释型语言.静态类型语言.动态类型语言概念与区别) https://www.cnblogs.com/zhoug2020/p/5972262.html Python解释 ...

  8. Python 浅析线程(threading模块)和进程(process)

    线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务 进程与线程 什么 ...

  9. python 多线程编程之使用进程和全局解释器锁GIL

    本文主要介绍如何在python中使用线程. 全局解释器锁: python代码的执行是由python虚拟机(又名解释器主循环)进行控制的.python中,主循环中同时只能有一个控制线程在执行,就像单核C ...

随机推荐

  1. springmvc pojo

    /** * Spring MVC 会按请求参数名和 POJO 属性名进行自动匹配, 自动为该对象填充属性值.支持级联属性. * 如:dept.deptId.dept.address.tel 等 */ ...

  2. java发送http请求和多线程

    0 概述 在写app后台的时候,需要调用另一个服务器上的算法服务,所以需要发送http请求来获取结果. 考虑到一个功能(比如智能中医)需要调用好几个接口(人脸识别,舌苔识别,饮食推荐),大部分时间花在 ...

  3. react下将输入的汉字转化为拼音

    1.首先需要一个简单的拼音和汉字对应的字典文件: /** * 收录常用汉字6763个,不支持声调,支持多音字,并按照汉字使用频率由低到高排序 */ var pinyin_dict_notone = { ...

  4. Linux系统服务管理 系统服务

    服务的分类 Linux 中的服务按照安装方法不同可以分为 RPM 包默认安装的服务和源码包安装的服务两大类.其中,RPM 包默认安装的服务又因为启动与自启动管理方法不同分为独立的服务和基于 xinet ...

  5. 在 Mac OS 上编译 OBS

    本文转自:在 Mac OS 上编译 OBS | www.samirchen.com 安装环境 第一步,做准备工作,安装编译 OBS 所需要的环境,流程如下: // 给当前用户添加 /usr/local ...

  6. MySQL Binlog解析(2)

    一.TABLE_MAP_EVENT Used for row-based binary logging beginning with MySQL 5.1.5.The TABLE_MAP_EVENT d ...

  7. springboot创建多环境profile打包

    springboot开发打包时,一般会有多个环境,dev,qa,prod等,配置文件大多雷同,只是方便开发切换,但是生成部署时产生的war包就无需这么多重复配置了,这时这些dev,qa的配置就不应该打 ...

  8. Effective C++ 条款05:了解C++编写并调用哪些函数

    规则一 编译器默认操作 // 你认为 class Empty { }; // 实际上 class Empty { public: Empty() { ... } // default 构造函数 Emp ...

  9. ThinkPHP3.2添加scws中文分词

    前言 前一段时间,公司网站做站内搜索,只简单针对输入的文字进行搜索,作全匹配检索,搜索出来的内容很少.如何达到模糊搜索,匹配到更多的内容成了需要解决的问题.于是,今天想到可以做分词检索,如何对输入的一 ...

  10. poj2349 Arctic Network - 最小生成树

    2017-08-04 16:19:13 writer:pprp 题意如下: Description The Department of National Defence (DND) wishes to ...