线程

go语言之goroute协程

早过忘川 提交于 2020-03-02 10:10:42
goroute协程 进程和线程 进程是系统进行资源分配和调度的基本单位,线程是cpu调度和发派的基本单位,一个进程可以创建和撤销多个线程 并发和并行 多线程程序在一个核的cpu上面运行,是并发 多线程程序在多个核的cpu上面运行,这是并行 协程和线程 协程 : 独立的栈空间,共享的堆内存,调度由用户自己控制,本质上有点类似于用户级的线程,这些用户级线程的调度是自己来实现的。 线程:一个线程可以跑多个协程。 一个简单的并发案例 这块两个协程会打印出hello和world package main import( "fmt" "time" ) func test(){ for{ fmt.Println("hello") time.Sleep(time.Second) } } func main(){ go test() for{ fmt.Println("world") time.Sleep(time.Second) } }    来源: https://www.cnblogs.com/mo3408/p/12394003.html

OO第二单元总结

ぃ、小莉子 提交于 2020-03-02 08:30:45
概述: 第二单元的主要内容是通过编写多线程程序来模拟电梯的运行。第一次作业是单傻瓜电梯,不考虑策略,基本是初步了解多线程程序的编写;第二次作业是单ALS电梯,在上一次的基础上要实现捎带,尽可能在最短时间内完成所有请求;第三次作业是多电梯,每个电梯可停的层和容量都不同,需要考虑乘客换乘的情况。在这三次作业中,我们的程序需要使用不同的策略将线程安全贯彻始终,以免出现与期望不符的BUG,我认为这也是多线程程序编程中的重点所在。 一、程序分析 1、第一次作业 (1) 设计策略    第一次作业要实现一个傻瓜电梯,思路很简单,可以看作一个传统的生产者-消费者的问题。考虑一个输入线程作为生产者,电梯线程作为一个消费者,维护一个线程安全的共享队列作为托盘(这里我使用了JDK自带的ConcurrentLinkedQueue)。输入线程每次向队列输入请求,无请求时结束;电梯线程的调度策略就是每次从队列中取出一个请求来完成,当队列为空且输入线程结束时结束。 (2) 度量分析 代码规模 类图 复杂度分析   本次作业需求比较简单,所以方法的复杂度都不高,最高就是5。 协作图 SOLID原则    本次作业输入线程只负责输入,电梯线程负责运行和输出,调度器作为共享对象被前二者共享,符合单一责任原则(SRP)。其他原则个人认为由于本次作业要求都无需考虑。 (3) BUG分析   

OO第二单元总结——电梯

我与影子孤独终老i 提交于 2020-03-02 08:30:12
第一次作业——FAFS调度 1.设计策略 第一次作业是单部电梯的傻瓜调度,所以电梯的运作不是难点。对于初次接触多线程的我来说,多线程之间的协同和同步控制是这次作业的难点。作业的整体思路我采用的是典型的 生产者-消费者模式 ,请求输入是一个生产者线程,调度器相当于一个仓库,电梯则是消费者线程。 我采用的是 共享对象 来实现的多线程间的同步控制,输入请求线程中有一个判断输入是否结束的共享变量,调度器中有一个当前队列是否为空的共享变量。关于多线程的协同,我采用的是轮询的方法来控制电梯线程。第一次并不太会使用wait和notify等,导致采用暴力轮询的方法CPU占用率偏高。 2.基于度量分析程序结构 类图 这四个类的功能较为独立且简单。RequestInput 是输入线程,Dispatcher 是调度器,ElevatorRun是电梯线程。输入线程和电梯线程分别组合同一个调度器来实现线程间的交互。 傻瓜电梯的Complexity Metrcis 分析结果中可以看到ev, iv, v这几栏,分别代指基本复杂度(Essential Complexity (ev(G))、模块设计复杂度(耦合度)(Module Design Complexity (iv(G)))、Cyclomatic Complexity (v(G))圈复杂度(独立路径的条数)。 OCavg 和 WMC 两个项目

北航OO第二单元总结

和自甴很熟 提交于 2020-03-02 08:29:29
第二单元主要的任务是设计电梯的调度,主要的难点在于多线程的控制,需要考虑同时可以被多个线程访问的数据的安全。 一、第一次作业 1、类图:主要设计了三个类,电梯类,控制器类,Main函数,其中有三个线程,输入线程,控制器线程,电梯线程,输入线程将乘客数据传入控制器,再由控制器分发给电梯,电梯负责乘客的具体配送 2、复杂度分析 第一次作业总体复杂度较低,说明设计的还算可以接受 3、优缺点分析:第一次作业个人感觉设计的较为流畅,但还是隐藏了一些问题在下一次作业才能发现,主要包括控制器线程究竟扮演了什么角色,因为后来讨论发现其实控制器可以不作为一个线程,可以通过一定的调度策略在输入到来时直接进行分配,而不需要单独的将控制器作为线程运行,否则控制器和电梯之间的逻辑关系在设计中稍显混乱,究竟什么时候结束整个程序难以判断。 4、主要难点:对于访问数据的控制,因为第一次作业控制器内的乘客队列是电梯和输入同时可以读写的,这部分的访问控制需要做好,其次需要注意的是主线程结束的时候不代表程序全部结束,笔者第一次写的时候线程内部都写成了死循环导致评测超时,最后分析想到主线程结束在本次作业中代表输入线程,输入结束不代表电梯运行结束,想通此点就知道之前的错误想法是稍显可笑的。 二、第二次作业 1、类图:和上次作业相同的三个类,区别是这一次Controller我没有将他作为一个线程,只是作为一个类

OO第二单元总结

流过昼夜 提交于 2020-03-02 08:29:05
概述 OO第二单元的作业主要是多线程的学习和使用。第一次作业只有一个傻瓜电梯,第二次作业是带捎带的电梯,而最后一次作业是三部带优化与特定条件的电梯,作业的实现难度也越来越大。 第一次作业 设计策略** 第一次作业简单的采用消费者生产者模型,使用电梯和输入两个线程,获取请求时对请求队列加锁加锁。电梯完成一个请求后从请求队列中取出一个请求。队列为空但输入线程未结束时就等待输入线程再次输入;直到输入线程结束并且所有人都到达了目的楼层之后就结束。 复杂度分析 类图 度量分析 elevator中的 run() 方法因为承担着电梯的运行与交互任务,所以iv(G)和整体的v(G)偏高;电梯由于是傻瓜电梯,没有一定的优化调度策略;电梯的运行判断都集中在了该类导致该类的循环复杂度过高。导致OCavg和WMC偏高。 1.3 UML协作图 第二次作业 设计策略** 电梯不断的与调度器进行交互来而更新策略,进行人员的捎带。根据规定的捎带原则进行对人员的捎带,电梯在无请求时进入wait状态,有新请求入队时将其唤醒并采用特定的规则进行捎带。run()方法与其他方法的紧密程度很高,在这个方法中也使用调度器对电梯运行方向的其余楼层进行遍历,判断电梯是否需要转向,从而避免遍历判断的。 复杂度分析 类图 度量分析 UML协作图 第三次作业 设计策略** 由于加入了换乘操作,使用了一个主调度器和三个子调度器

跨线程间的定时器机制----QTimer和QThread

做~自己de王妃 提交于 2020-03-02 07:30:20
跨线程使用定时器机制在博客 http://www.cnblogs.com/lingdhox/p/4218051.html 中做了详细的介绍,给出了两种常用的实现方式的具体实现,但并没有给出为什么定时器的溢出信号与槽方法的关联中使用Qt::DirectConnection方式。 如果信号与槽的连接方式使用默认方式( Qt::AutoConnection ),会发生什么? 定时器当slot的object是其他线程(不妨称为Thread1)时,会自动post事件到线程Thread1的事件循环系统。一方面,如果slot处理函数不是线程安全函数,定时器溢出信号到达slot处理函数时,slot处理函数有可能正在响应对象自身的调用,出现多个线程同时访问slot处理函数的情形,可能导致错误甚至系统崩溃。另一方面,即使slot处理函数是线程安全的,事件循环系统可能会导致定时器的响应事件出现延迟,对时间精度要求较高的环境,可能会导致错误。 来源: CSDN 作者: beibeix2015 链接: https://blog.csdn.net/beibeix2015/article/details/78738694

python之线程

大憨熊 提交于 2020-03-02 04:01:09
什么是线程? 线程是CPU上的执行单位。 线程和进程的区别 1、进程是资源的集合,是一个资源单位。线程是CPU上是执行单位。所以开进程开销与远大于开线程 2、进程单独开辟内存空间。同一个进程内多线程共享同一个内存空间 a = 100 def task(): global a a = 0 if __name__ == '__main__': # p = Process(target=task, ) # p.start() # p.join() # print(a) # 100 t = Thread(target=task, ) t.start() t.join() print(a) # 0 3、开多个进程,每个进程有不同的pid。在主进程下开启多个线程,每个线程的pid和主进程的pid一样 Thread对象的其他用法 from threading import Thread, current_thread, active_count, enumerate import time def task(): print("子进程", current_thread().getName(), current_thread().name) # current_thread().getName() == current_thread().name time.sleep(2) if __name__

android学习笔记----定时问题

☆樱花仙子☆ 提交于 2020-03-02 03:48:28
两种方法: 第一种: // 5000ms后执行run方法 // 可以在这run()里面更新ui new Handler().postDelayed(new Runnable() { @Override public void run() { tv.setText("呵呵呵呵呵"); Log.d(TAG, "5s后我执行了"); } }, 5000); 上面效果就是5s后将TextView控件内容改为“呵呵呵呵呵” 第二种: timer = new Timer(); // 不能在这run()里面更新ui,除非使用runOnUiThread方法 timerTask = new TimerTask() { @Override public void run() { tv.setText("哈哈哈哈哈"); Log.d(TAG, "任务执行"); } }; timer.schedule(timerTask, 2000, 2000); timer.schedule的第三个参数是间隔多久重复一次,可以不设置,做一次性的任务。 如果设置第三个参数就要记得在OnDestroy取消,不然activity销毁后定时任务仍然存在。 如果在这里的run方法更新ui就需要使用runOnUiThread()方法。 下面效果是每隔2s将TextView控件内容设置为“哈哈哈哈哈” timer = new

多线程进阶——JUC并发编程之Synchronized底层实现概论🔥

 ̄綄美尐妖づ 提交于 2020-03-02 01:07:17
1、Synchronized简介 Java中提供了两种实现同步的基础语义: synchronized 方法和 synchronized 块 ,下面我们来操作一番: public class SyncTest { public void syncBlock(){ synchronized (this){ System.out.println("sync block balabala...."); } } public synchronized void syncMethod(){ System.out.println("sync method hahaha...."); } public static void main(String[] args) { } } 将SyncTest.java 编译为SyncTest,.class文件,我们使用 javap -v SyncTest.class 查看class文件对应的JVM字节码信息。这里我使用的是JVM版本是JDK1.8。 { ... public void syncBlock(); descriptor: ()V flags: ACC_PUBLIC Code: stack=2, locals=3, args_size=1 0: aload_0 1: dup 2: astore_1 3: monitorenter 4:

生产者消费者的几种写法

感情迁移 提交于 2020-03-02 00:50:39
我自己根据理解写了4种,可能会存在问题,望指正! 问题描述: 开5个线程,作为生产者线程,每个线程往容器里放3个; 开5个消费者线程,每个线程从容器里get3次; 如果容器满了,生产者阻塞; 如果容器空了,消费者阻塞。 1.用一个普通的数据结构如ArrayList来实现。 利用synchronized和Object自带的wait()/notifyAll()方法实现。 public static void main(String[] args) { List<Integer> c=new ArrayList<Integer>(5); //producer for(int i=0;i<5;i++) { new Thread(()->{ for(int j=0;j<3;j++) { while(true) { synchronized(c) { if(c.size()<5) { c.add(j); System.out.println(Thread.currentThread().getName()+"product "+j); c.notifyAll(); break; }else { try { c.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } } } },String.valueOf(i)