python多线程

多核CPU上python多线程并行的一个假象

天涯浪子 提交于 2019-12-05 20:38:50
多核CPU上python多线程并行的一个假象 python-cn(华蟒用户组,CPyUG 邮件列表)上: 关于 python 多线程是否能用到多核的问题 相关讨论 本机环境: 2核CPU, linux 2.6, python 2.6.2 在python上开启多个线程,由于GIL的存在,每个单独线程都会在竞争到GIL后才 运行,这样就干预OS内部的进程(线程)调度,结果在多核CPU上: python的多线程实际是串行执行的,并不会同一时间多个线程分布在多个CPU上运行。 但是这里有个有趣的现象: python开启两个死循环的线程,在我的2核机器上会有如下 CPU使用情况,每个CPU都维持在50%左右的使用率(见下图). 难道python的多线程可以在多核上并行? 当然不是,在GIL存在的python上,多线程应该是不可能并行的。 这里其实有个小细节隐藏在linux的进程调度系统内,当python多线程切换时候,linux 调度子系统会兼顾多核的负载情况,linux会把多个线程平均分布在多核上跑,这样不 会导致单个核负载过盛。但是这个并不会让python多线程在多核上并行。 大致CPU使用应该这样: cpu0: .. pythread0 _________ pythread0 _________ .. cpu1: .. _________ pythread1 _________

python多线程为什么不能利用多核cpu

时光怂恿深爱的人放手 提交于 2019-12-05 20:37:46
GIL 与 Python 线程的纠葛 GIL 是什么东西?它对我们的 python 程序会产生什么样的影响?我们先来看一个问题。运行下面这段 python 程序,CPU 占用率是多少? 请勿在工作中模仿,危险:) def dead_loop(): while True: pass dead_loop() 答案是什么呢,占用 100% CPU?那是单核!还得是没有超线程的古董 CPU。在我的双核 CPU 上,这个死循环只会吃掉我一个核的工作负荷,也就是只占用 50% CPU。那如何能让它在双核机器上占用 100% 的 CPU 呢?答案很容易想到,用两个线程就行了,线程不正是并发分享 CPU 运算资源的吗。可惜答案虽然对了,但做起来可没那么简单。下面的程序在主线程之外又起了一个死循环的线程 import threading def dead_loop(): while True: pass 新起一个死循环线程 t = threading.Thread(target=dead_loop) t.start() 主线程也进入死循环 dead_loop() t.join() 按道理它应该能做到占用两个核的 CPU 资源,可是实际运行情况却是没有什么改变,还是只占了 50% CPU 不到。这又是为什么呢?难道 python 线程不是操作系统的原生线程?打开 system monitor 一探究竟

Java 复习笔记8 - 多线程

谁都会走 提交于 2019-12-05 20:13:28
概念 关于什么是线程,进程等概念,请看下面文章: 并发/并行/阻塞/非阻塞 多进程概念 多线程概念 上述文章代码使用的是python,但是所有的概念和原理都是相同的; 需要特别强调的是Java中的线程在多核处理器上是可以真正并行执行的,没有cpython中的全局锁这么一说 线程的状态切换以及生命周期: 注意:stop方法以及被弃用建议不要使用了,线程正确的结束,应该是线程任务全部完成,或者是被作为守护线程,被守护线程运行结束,再或者调用中断方法 interrupt Java中启动线程的方式: package com.yh.lesson.collection.thread; import sun.nio.ch.ThreadPool; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class Test { public static void main(String[] args) { //1.匿名类 Thread td1 = new Thread(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName());

python线程事件Event(30)

╄→гoц情女王★ 提交于 2019-12-05 19:41:10
在python项目开发中,线程thread使用是比较常见的,在前面的文章中我们介绍了 python线程的创建 以及 线程互斥锁 ,今天还要额外介绍一个与线程相关的内容 – 事件Event。 一.python事件Event相关函数介绍 set() — 全局内置标志Flag,将标志Flag 设置为 True,通知在等待状态(wait)的线程恢复运行; isSet() — 获取标志Flag当前状态,返回True 或者 False; wait() — 一旦调用,线程将会处于阻塞状态,直到等待其他线程调用set()函数恢复运行; clear() — 将标志设置为False; 二.python事件Event原理 事件event中有一个全局内置标志Flag,值为 True 或者False。使用wait()函数的线程会处于阻塞状态,此时Flag指为False,直到有其他线程调用set()函数让全局标志Flag置为True,其阻塞的线程立刻恢复运行,还可以用isSet()函数检查当前的Flag状态. 三.python事件Event使用 假如有这样一个场景:有10个单身狗,对面100米有10个美女,同时起跑,一人一个,自由选择,先到先得….. # !usr/bin/env python # -*- coding:utf-8 _*- """ @Author:何以解忧 @Blog(个人博客地址):

python进程和线程

丶灬走出姿态 提交于 2019-12-05 19:00:32
1.多进程 针对unix/linux操作系统会提供一个 fork() 系统调用,其调用一次,返回两次,因为操作系统自动把当前文件复制了一份,称为父进程和子进程 子进程永远返回0,而父进程返回子进程的ID,这样一个父进程可以fork出很多子进程,so父进程要记下每个子进程的ID,而子进程通过调用getppid()拿到父进程的ID python中的os模块封装了常见的系统调用,其中包括fork 1)Mutiprocessing 跨平台版本的多进程模块,提供 process 类来代表一个进程对象 from multiprocessing import Process import os #子进程要执行的代码 def run_proc(name): print("run child process %s(%s)..."%(name,os.getpgid())) if _name_== '_main_': print(("parent process %s"%os.getpgid())) p = Process(target=run_proc,args=("test",)) print("child process will start") p.start() p.join() print("child will end") 2)pool 如果启动大量的子进程

python线程互斥锁Lock(29)

落爺英雄遲暮 提交于 2019-12-05 18:10:31
在前一篇文章 python线程创建和传参 中我们介绍了关于python线程的一些简单函数使用和线程的参数传递,使用多线程可以同时执行多个任务,提高开发效率,但是在实际开发中往往我们会碰到线程同步问题,假如有这样一个场景:对全局变量累加1000000次,为了提高效率,我们可以使用多线程完成,示例代码如下: # !usr/bin/env python # -*- coding:utf-8 _*- """ @Author:何以解忧 @Blog(个人博客地址): shuopython.com @WeChat Official Account(微信公众号):猿说python @Github:www.github.com @File:python_thread_lock.py @Time:2019/10/17 21:22 @Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累! """ # 导入线程threading模块 import threading # 声明全局变量 g_num = 0 def my_thread1(): # 声明全局变量 global g_num # 循环 1000000 次,每次累计加 1 for i in range(0,1000000): g_num = g_num + 1 def my_thread2(): # 声明全局变量

python并发——信号量

怎甘沉沦 提交于 2019-12-05 17:30:44
信号量通常用于保护数量有限的资源,例如数据库服务器。在资源数量固定的任何情况下,都应该使用有界信号量。在生成任何工作线程前,应该在主线程中初始化信号量。 工作线程生成后,当需要连接服务器时,这些线程将调用信号量的 acquire 和 release 方法: 使用有界信号量能减少这种编程错误:信号量的释放次数多于其请求次数。 from threading import BoundedSemaphore maxconnections = 5 pool_sema = BoundedSemaphore(value=maxconnections) with pool_sema: conn = connectdb() try: do_some() finally: conn.close() 来源: https://www.cnblogs.com/wangbin2188/p/11937111.html

多线程爬虫案例

百般思念 提交于 2019-12-05 15:15:10
Queue(队列对象) Queue是python中的标准库,可以直接import Queue引用;队列是线程间最常用的交换数据的形式 python下多线程的思考 对于资源,加锁是个重要的环节。因为python原生的list,dict等,都是not thread safe的。而Queue,是线程安全的,因此在满足使用条件下,建议使用队列 初始化: class Queue.Queue(maxsize) FIFO 先进先出 包中的常用方法: Queue.qsize() 返回队列的大小 Queue.empty() 如果队列为空,返回True,反之False Queue.full() 如果队列满了,返回True,反之False Queue.full 与 maxsize 大小对应 Queue.get([block[, timeout]])获取队列,timeout等待时间 创建一个“队列”对象 import Queue myqueue = Queue.Queue(maxsize = 10) 将一个值放入队列中 myqueue.put(10) 将一个值从队列中取出 myqueue.get() 多线程示意图 # -*- coding:utf-8 -*- # 使用了线程库 import threading # 队列 from Queue import Queue # 解析库 from lxml

python 线程创建和传参(28)

点点圈 提交于 2019-12-05 14:20:23
在以前的文章中虽然我们没有介绍过线程这个概念,但是实际上前面所有代码都是线程,只不过是单线程,代码由上而下依次执行或者进入main函数执行,这样的单线程也称为主线程。 有了单线程的话,什么又是多线程?可以这么理解:一个线程执行一个代码块,多个线程可以同时执行多个代码,使用多线程能让程序效率更高。举个例子,你今天有两件事需要完成,分别是洗衣服和打扫房间,分别来看看单线程和多线程如何完成: 单线程:先用洗衣机洗衣服30分钟,等衣服洗完之后再打扫房间60分钟,累计总耗时:90分钟; 多线程:把衣服放到洗衣机并且30分钟后自动结束,然后立刻开始打扫房间60分钟,累计耗时:60分钟; 由此可见,完成同样的事情,单线程是一件事情做完之后继续下一件事情,而多线程可以同时执行多件事情,所以多线程比单线程效率更高! 一.线程解释 线程是cpu最小调度单位,一个程序中至少有一个或者多个线程(至于进程暂时不做讲解,后面文章会有详细解释)!在开发中使用线程可以让程序运行效率更高,多线程类似于同时执行多个不同代码块。 二.线程创建和启动 1.导入线程模块 # 导入线程threading模块 import threading 2.创建线程并初始化线程 调用threading模块中的缺省函数Thread,创建并初始化线程,返回线程句柄。如果对缺省函数已经忘记的小伙伴请回到 python函数的声明和定义

python多进程、多线程

痞子三分冷 提交于 2019-12-05 09:09:26
一:多线程和多进程 进程是多个资源的集合。 线程是就是进程里面具体干活的。 线程和线程之间是互相独立的。 二:多线程使用threading模块 启用多线程: import threading def down_load(): time.sleep(5) print("运行完了") t = threading.Thread(target=down_load,args=('name','abfd')) #生成一个线程实例 t.start 启动线程 复制代码 线程等待: import threading import time def down_load(): time.sleep(5) print("运行完了") start_time = time.time() for i in range(5): t = threading.Thread(target=down_load) t.start() while threading.activeCount()!=1: pass print(threading.activeCount()) #查看当前线程数 print(threading.current_thread())#查看当前线程 end_time = time.time() print(end_time - start_time) 复制代码 下载图片: import requests