精华内容
下载资源
问答
  • 一个程序,有两个功能: 读数据,写数据(仅有这两...单线程的程序流程是:顺序执行,先读数据,再写数据 多线程程序流程:开两个线程,读线程和写线程,但是是读线程执行完毕后通知写线程. 在多任务OS下,两者速度有差距吗?谢谢
  • pyrhon视频教程栏目介绍多线程是否真的比单线程快。事实上,Python 多线程另一个很重要的话题叫,GIL(Global Interpreter Lock,即全局解释器锁)。多线程不一定比单线程快在Python中,可以通过多进程、多线程和多...

    pyrhon视频教程栏目介绍多线程是否真的比单线程快。

    66efcd0419141a93899f63f0aa3d1bc6.png

    事实上,Python 多线程另一个很重要的话题叫,GIL(Global Interpreter Lock,即全局解释器锁)。

    多线程不一定比单线程快

    在Python中,可以通过多进程、多线程和多协程来实现多任务。难道多线程就一定比单线程快?

    下面我用一段代码证明我自己得观点。'''

    @Author: Runsen

    @微信公众号: Python之王

    @博客: https://blog.csdn.net/weixin_44510615

    @Date: 2020/6/4

    '''import threading, timedef my_counter():

    i = 0

    for _ in range(100000000):

    i = i+1

    return Truedef main1():

    start_time = time.time() for tid in range(2):

    t = threading.Thread(target=my_counter)

    t.start()

    t.join() # 第一次循环的时候join方法引起主线程阻塞,但第二个线程并没有启动,所以两个线程是顺序执行的

    print("单线程顺序执行total_time: {}".format(time.time() - start_time))def main2():

    thread_ary = {}

    start_time = time.time() for tid in range(2):

    t = threading.Thread(target=my_counter)

    t.start()

    thread_ary[tid] = t for i in range(2):

    thread_ary[i].join() # 两个线程均已启动,所以两个线程是并发的

    print("多线程执行total_time: {}".format(time.time() - start_time))if __name__ == "__main__":

    main1()

    main2()复制代码

    运行结果单线程顺序执行total_time: 17.754502773284912多线程执行total_time: 20.01178550720215复制代码

    我怕你说我乱得出来得结果,我还是截个图看清楚点

    a8165595d3454738440e1fb17f0502a1.png

    这时,我怀疑:我的机器出问题了吗?其实不是这样,本质上来说Python 的线程失效了,没有起到并行计算的作用。

    Python 的线程,的确封装了底层的操作系统线程,在 Linux 系统里是 Pthread(全称为 POSIX Thread),而在 Windows 系统里是 Windows Thread。另外,Python 的线程,也完全受操作系统管理,比如协调何时执行、管理内存资源、管理中断等等。

    GIL不是Python的特性

    GIL 的概念用简单的一句话来解释,就是任一时刻,无论线程多少,单一 CPython 解释器只能执行一条字节码。这个定义需要注意的点:

    首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。

    C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码。有名的编译器例如GCC,INTEL C++,Visual C++等。

    Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行。

    其他 Python 解释器不一定有 GIL。例如 Jython (JVM) 和 IronPython (CLR) 没有 GIL,而 CPython,PyPy 有 GIL;

    因为CPython是大部分环境下默认的Python执行环境。所以在很多人的概念里CPython就是Python,也就想当然的把GIL归结为Python语言的缺陷。所以这里要先明确一点:GIL并不是Python的特性,Python完全可以不依赖于GIL

    GIL本质就是一把互斥锁

    GIL本质就是一把互斥锁,既然是互斥锁,所有互斥锁的本质都一样,都是将并发运行变成串行,以此来控制同一时间内共享数据只能被一个任务所修改,进而保证数据安全。

    可以肯定的一点是:保护不同的数据的安全,就应该加不同的锁。

    GIL 的工作原理:比如下面这张图,就是一个 GIL 在 Python 程序的工作示例。其中,Thread 1、2、3 轮流执行,每一个线程在开始执行时,都会锁住 GIL,以阻止别的线程执行;同样的,每一个线程执行完一段后,会释放 GIL,以允许别的线程开始利用资源。

    03122cb0e0c81c96a0f51931909d8759.png

    计算密集型

    计算密集型任务的特点是要进行大量的计算,消耗CPU资源。

    我们先来看一个简单的计算密集型示例:'''

    @Author: Runsen

    @微信公众号: Python之王

    @博客: https://blog.csdn.net/weixin_44510615

    @Date: 2020/6/4

    '''import time

    COUNT = 50_000_000def count_down():

    global COUNT while COUNT > 0:

    COUNT -= 1s = time.perf_counter()

    count_down()

    c = time.perf_counter() - s

    print('time taken in seconds - >:', c)

    time taken in seconds - >: 9.2957003复制代码

    这个是单线程, 时间是9s, 下面我们用两个线程看看结果又如何:'''

    @Author: Runsen

    @微信公众号: Python之王

    @博客: https://blog.csdn.net/weixin_44510615

    @Date: 2020/6/4

    '''import timefrom threading import Thread

    COUNT = 50_000_000def count_down():

    global COUNT while COUNT > 0:

    COUNT -= 1s = time.perf_counter()

    t1 = Thread(target=count_down)

    t2 = Thread(target=count_down)

    t1.start()

    t2.start()

    t1.join()

    t2.join()

    c = time.perf_counter() - s

    print('time taken in seconds - >:', c)

    time taken in seconds - >: 17.110625复制代码

    我们程序主要的操作就是在计算, CPU没有等待, 而改为多线程后, 增加了线程后, 在线程之间频繁的切换,增大了时间开销, 时间当然会增加了。

    还有一种类型是IO密集型,涉及到网络、磁盘IO的任务都是IO密集型任务,这类任务的特点是CPU消耗很少,任务的大部分时间都在等待IO操作完成(因为IO的速度远远低于CPU和内存的速度)。对于IO密集型任务,任务越多,CPU效率越高,但也有一个限度。常见的大部分任务都是IO密集型任务,比如Web应用。

    总结:对于io密集型工作(Python爬虫),多线程可以大幅提高代码效率。对CPU计算密集型(Python数据分析,机器学习,深度学习),多线程的效率可能比单线程还略低。所以,数据领域没有多线程提高效率之说,只有将CPU提升到GPU,TPU来提升计算能力。

    展开全文
  • 我想检查多线程是否比单线程,然后我在这里做一个演示:public class ThreadSpeedTest {/*** @param args*/public static void main(String[] args) {System.out.println("cpu number:"+ Runtime.getRuntime()....

    我想检查多线程是否比单线程更快,然后我在这里做一个演示:

    public class ThreadSpeedTest {

    /**

    * @param args

    */

    public static void main(String[] args) {

    System.out.println("cpu number:"

    + Runtime.getRuntime().availableProcessors());

    singleThreadStart();

    // secondThreadStart();

    // fiveThreadStart();

    }

    private static void sum() {

    long sum = 0;

    for (int i = 0; i < 1000000; i++) {

    sum += i;

    }

    System.out.println(sum);

    }

    private static void singleThreadStart() {

    new Thread(new Runnable() {

    public void run() {

    long start = System.nanoTime();

    // sum();

    // sum();

    // sum();

    sum();

    sum();

    long end = System.nanoTime();

    System.out.println("cost time:" + (end - start));

    }

    }).start();

    }

    private static void secondThreadStart() {

    long start = System.nanoTime();

    Thread thread1 = new Thread(new Runnable() {

    public void run() {

    sum();

    }

    });

    thread1.start();

    Thread thread2 = new Thread(new Runnable() {

    public void run() {

    sum();

    }

    });

    thread2.start();

    try {

    thread1.join();

    thread2.join();

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    long end = System.nanoTime();

    System.out.println("cost time:" + (end - start));

    }

    private static void fiveThreadStart() {

    long start = System.nanoTime();

    Thread thread1 = new Thread(new Runnable() {

    public void run() {

    sum();

    }

    });

    thread1.start();

    Thread thread2 = new Thread(new Runnable() {

    public void run() {

    sum();

    }

    });

    thread2.start();

    Thread thread3 = new Thread(new Runnable() {

    public void run() {

    sum();

    }

    });

    thread3.start();

    Thread thread4 = new Thread(new Runnable() {

    public void run() {

    sum();

    }

    });

    thread4.start();

    Thread thread5 = new Thread(new Runnable() {

    public void run() {

    sum();

    }

    });

    thread5.start();

    try {

    thread1.join();

    thread2.join();

    thread3.join();

    thread4.join();

    thread5.join();

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    long end = System.nanoTime();

    System.out.println("cost time:" + (end - start));

    }

    }

    首先我使用两个sum方法运行singleThreadStart,结果是

    cpu number:4

    499999500000

    499999500000

    cost time:6719000

    然后我运行secondThreadStart,结果是

    cpu number:4

    499999500000

    499999500000

    cost time:14299000

    然后我用五个sum方法运行singleThreadStart,结果是

    cpu number:4

    499999500000

    499999500000

    499999500000

    499999500000

    499999500000

    cost time:10416000

    最后我运行fiveThreadStart,结果是

    cpu number:4

    499999500000

    499999500000

    499999500000

    499999500000

    499999500000

    cost time:15708000

    我的问题是:

    1.SecondThreadStart比singleThreadStart花费的时间更多,是不是因为创建线程的成本?

    2.尽管创建线程的成本很高,但是cpu数是4,那么使用超过4个线程会比使用4个线程慢吗?

    3.如果我想做一些花费更多时间的事情,使用四个线程做的最好吗?

    解决方法:

    1.SecondThreadStart cost more time than singleThreadStart, is it because the cost of creating thread?

    当然,创建线程会产生开销.

    2.The cpu number is 4, despite the cost of creating thread, so using thread number more than 4 will slower than using four threads?

    如果线程很快完成(不受IO限制和CPU限制),即使线程数超过CPU核心数,也可以获得良好的结果.

    3.If I want to do something cost much time, using four threads to do is best?

    您可以使用高级java并发类(执行者的newWorkStealingPool)

    请参阅此SE问题:

    一般来说:

    多线程可以通过使用更多CPU功率来提高应用程序的吞吐量.

    这取决于很多因素.

    >线程数

    > CPU核心

    >线程创建成本和上下文切换(可能对多线程有效)

    >数据结构

    >数据的可变性(可能对多线程有效)

    >共享访问/数据结构的并发(可能对多线程有效)

    >应用程序类型:CPU绑定或IO绑定

    如果您的应用程序是多线程将提供出色的结果

    >更少的CPU限制,更少的IO绑定(但仍然可以使用多线程这些应用程序)

    >没有共享数据

    如果不是,性能取决于上述因素,单线程应用程序和多线程应用程序之间的吞吐量会有所不同.

    一些好的SE问题:

    好文章:

    标签:java,multithreading,processor

    来源: https://codeday.me/bug/20190527/1167062.html

    展开全文
  • 在Windows编程中,多线程一定比单线程快吗?什么时候该用多线程?什么时候该用单线程?它们各自的应用场景是什么?
  • 多线程一定比单线程快吗

    千次阅读 2018-10-24 19:22:21
    不一定。因为,存在线程创建和上下文切换的时间开销。

    不一定。因为,存在线程创建和上下文切换的时间开销。

    展开全文
  • 多线程并发一定比单线程快吗

    千次阅读 2019-08-02 19:19:54
    确实多线程在一定情况下比单线程更快。 下面的代码演示串行和并发执行并累加操作的时间,请分析:当count的数量增加 1万 -> 10万 -> 100万 -> 1000万 -> 1亿,下面的代码并发执行一定比串行执行快吗?...

    很多时候我们都以为要想处理速度更快,那就多开几个线程跑! 确实多线程在一定情况下比单线程更快。

    下面的代码演示串行和并发执行并累加操作的时间,请分析:当count的数量增加 1万 -> 10万 -> 100万 -> 1000万 -> 1亿,下面的代码并发执行一定比串行执行快吗?

    public class ConcurrencyTest {
        private static final long count = 10000l;
    
        public static void main(String[] args) throws InterruptedException {
            for(int i=0; i<10; i++) {
                concurrency();
                serial();
                System.out.println("------------------------------------------");
            }
    
        }
    
        private static void concurrency() throws InterruptedException {
            long start = System.currentTimeMillis();
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    int a = 0;
                    for (long i = 0; i < count; i++) {
                        a += 5;
                    }
                }
            });
            thread.start();
            int b = 0;
            for (long i = 0; i < count; i++) {
                b--;
            }
            long time = System.currentTimeMillis() - start;
            thread.join();
            System.out.println("concurrency :" + time + "ms,b=" + b);
        }
    
        private static void serial() {
            long start = System.currentTimeMillis();
            int a = 0;
            for (long i = 0; i < count; i++) {
                a += 5;
            }
            int b = 0;
            for (long i = 0; i < count; i++) {
                b--;
            }
            long time = System.currentTimeMillis() - start;
            System.out.println("serial:" + time + "ms,b=" + b + ",a=" + a);
        }
    }

    测试结果

    这是count=1万的结果,基本上串行要快些

    并发 :1ms,b=-10000
    串行:0ms,b=-10000,a=50000
    ------------------------------------------
    并发 :0ms,b=-10000
    串行:1ms,b=-10000,a=50000
    ------------------------------------------
    并发 :0ms,b=-10000
    串行:1ms,b=-10000,a=50000
    ------------------------------------------
    并发 :0ms,b=-10000
    串行:0ms,b=-10000,a=50000
    ------------------------------------------
    并发 :1ms,b=-10000
    串行:0ms,b=-10000,a=50000
    ------------------------------------------
    并发 :1ms,b=-10000
    串行:0ms,b=-10000,a=50000
    ------------------------------------------
    并发 :0ms,b=-10000
    串行:1ms,b=-10000,a=50000
    ------------------------------------------
    并发 :0ms,b=-10000
    串行:0ms,b=-10000,a=50000
    ------------------------------------------
    并发 :1ms,b=-10000
    串行:0ms,b=-10000,a=50000
    ------------------------------------------

    这是count=10万l的结果,基本上串行要快点点

    并发 :4ms,b=-100000
    串行:3ms,b=-100000,a=500000
    ------------------------------------------
    并发 :0ms,b=-100000
    串行:1ms,b=-100000,a=500000
    ------------------------------------------
    并发 :1ms,b=-100000
    串行:0ms,b=-100000,a=500000
    ------------------------------------------
    并发 :0ms,b=-100000
    串行:1ms,b=-100000,a=500000
    ------------------------------------------
    并发 :1ms,b=-100000
    串行:0ms,b=-100000,a=500000
    ------------------------------------------
    并发 :0ms,b=-100000
    串行:0ms,b=-100000,a=500000
    ------------------------------------------
    并发 :1ms,b=-100000
    串行:0ms,b=-100000,a=500000
    ------------------------------------------
    并发 :0ms,b=-100000
    串行:0ms,b=-100000,a=500000
    ------------------------------------------
    并发 :0ms,b=-100000
    串行:1ms,b=-100000,a=500000
    ------------------------------------------
    并发 :0ms,b=-100000
    串行:0ms,b=-100000,a=500000
    ------------------------------------------

    这是count=100万l的结果,基本上并发就要比串行要快了

    并发 :5ms,b=-1000000
    串行:5ms,b=-1000000,a=5000000
    ------------------------------------------
    并发 :3ms,b=-1000000
    串行:7ms,b=-1000000,a=5000000
    ------------------------------------------
    并发 :1ms,b=-1000000
    串行:7ms,b=-1000000,a=5000000
    ------------------------------------------
    并发 :1ms,b=-1000000
    串行:2ms,b=-1000000,a=5000000
    ------------------------------------------
    并发 :1ms,b=-1000000
    串行:2ms,b=-1000000,a=5000000
    ------------------------------------------
    并发 :2ms,b=-1000000
    串行:2ms,b=-1000000,a=5000000
    ------------------------------------------
    并发 :1ms,b=-1000000
    串行:3ms,b=-1000000,a=5000000
    ------------------------------------------
    并发 :1ms,b=-1000000
    串行:2ms,b=-1000000,a=5000000
    ------------------------------------------
    并发 :1ms,b=-1000000
    串行:3ms,b=-1000000,a=5000000
    ------------------------------------------
    并发 :1ms,b=-1000000
    串行:2ms,b=-1000000,a=5000000
    ------------------------------------------

    余下的读者可以自己去调试哦。

     

    结论

     1.在数量比较小的时候,很明显串行要比并发更快。

     2.因为数量较小的时候,并发会花费很多时间在线程调度上。

    展开全文
  • 为什么要使用多线程? 在探讨文章题目之前,我们先来思考这样一个问题,你为什么要使用多线程?我相信很多人在遇到这个...设想一下这样的一个场景,我们现在的程序是单线程的,而且代码中充斥着大量的读取文件内容的
  • 多线程并不一定比单线程耗时少,因为因为线程有创建和上下文切换的开销。 解决方法 减少上下文切换的方法有:无锁并发编程、CAS算法、使用最少线程和使用协程。 无锁并发编程 多线程竞争锁时,会引起上...
  • 欢迎各位Java工程师朋友投稿和关注一、思考人生的多线程我们一直在说高并发、多线程、分布式应用,但是高并发情况下,多线程一定就快吗?我们首先要理解下并发运行是怎么一回事。为什么一般意义上来说多线程就能抵抗...
  • 欢迎各位Java工程师朋友投稿和关注一、思考人生的多线程我们一直在说高并发、多线程、分布式应用,但是高并发情况下,多线程一定就快吗?我们首先要理解下并发运行是怎么一回事。为什么一般意义上来说多线程就能抵抗...
  • 我们一直在说高并发、多线程、分布式应用,但是高并发情况下,多线程一定就快吗? 我们首先要理解下并发运行是怎么一回事。 为什么一般意义上来说多线程就能抵抗高并发,运行速度就能得到提升? 所谓并发运行就是...
  • 昨天晚上做了个实验,用线程复制7个文件和单个线程复制7个文件(总共约1.7G)比较,代码如下:import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io....
  • 本文想从一个角度来让大家认识到回答一个问题不能从表面或者感觉来判断,这是学习技术的大忌,很新手如果刚开始没有一套学习方法,从各种碎片化信息去学习编程,学习一段时间很容易进入瓶颈期,所以我觉得有必要...
  • 多线程

    2018-06-04 15:53:09
    1、多线程比单线程快吗 大一般情况下,多线程是比单线程快的。但不是一定 在单核cpu的情况下,如果做的工作是cpu密集型的,开多个线程,反而有可能比线程要慢,线程间的切换是需要消耗资源和时间的。 但是,大...
  • 为什么这种python多线程方法要比单线程花费更多的时间来解决相同的问题?在我的电脑就是多核处理器。在我用两种方法编写了相同的代码,并进行了比较。令人惊讶的是单线程的方式更!有人有什么想法吗?在#!/usr/bin...
  • 甚至于认为使用多线程效率就比单线程要高。但事实真的如此吗?下面我们做一些测试 测试1-单线程执行效率 public static void main(String[] args) { Long start = System.currentTimeMillis(); // 总数据条...
  • 甚至于认为使用多线程比单线程要高大上、要好。但事实真的是这样吗?下面就举一个案列看看 1.使用ThreadPoolExecutor创建线程池(创建线程池有很多种方法,这里就不一一列举了) /** * 线程池类 */ public clas....
  • JAVA基础篇-多线程一定快吗

    千次阅读 2017-06-22 12:17:17
    下面的代码演示串行和并发执行并累加操作的时间,请分析:下面的代码并发执行一定串行执行快吗? package chapter01; //并发和单线程执行测试 public class ConcurrencyTest { /** 执行次数 */ private ...
  • 多线程从网上下载一个大文件为什么要更(单线程)?网上查了有人说“是因为io堵塞的原因,因为网速肯定不过cpu,单线程单io通道,而多线程多io通道“ 。我理解他的意思是:单线程因为网速慢赶不上cpu的处理...
  • 多线程从网上下载一个大文件为什么要更(单线程)?网上查了有人说“是因为io堵塞的原因,因为网速肯定不过cpu,单线程单io通道,而多线程多io通道“ 。我理解他的意思是:单线程因为网速慢赶不上cpu的处理...
  • 从单机到机:机一定单机快吗?秒杀到底有没有必要用分布式锁? 一、单机场景 单机能承受的 TPS tomcat 500~1000 mysql 200~800 在单机状态下,tomcat 能接受的请求肯定 mysql 更,此时数据库成为系统...
  • 前言当面试官问你Redis是单线程还是多线程?你肯定会说:单线程!然后他就会问:单线程为啥还这么?你就会说出这几条原因:1、Redis是基于内存的,内存的读写速度非常,从内存中拿数据从磁盘上更。2、Redis...
  • 有2种开工方法1、只在山的一头挖,直至挖到山的另一头,从而打通隧道,这可以看成是单线程2、在山的两头挖,同时开工,最后在山的中间接通,从而打通隧道,这感觉肯定1了很多,好比多线程但是2成立的前提是必须...
  • 多进程i/o 比单进程快吗Two notices: 1, a process has only one main thread which is itself. 2, a process has many threads. 有两个注意事项:1,一个进程只有一个主线程本身。 2,一个进程有很多线程。 ...

空空如也

空空如也

1 2 3 4 5 ... 8
收藏数 149
精华内容 59
关键字:

多线程比单线程快吗