多线程

阅读 / 问答 / 标签

JAVA多线程 模拟每隔一秒输入一个数据

对于读取字符类型的文件,直接使用增强流中的readLine,一次就是一行,不用你想的这么麻烦!

Netty的Reactor多线程模型,NioEventLoop,ChannelPipeline简介

如果在Google上搜索"Netty 高性能 易用",在找到的一大批文章,你大概率会看到这张图,外加关键字 NIO , Reactor多线程模型 , 异步串行无锁化 , 堆外内存 , pipeline ,翻看完这些文章后可以让你对Netty的原理有大致了解,但是Netty如何实现这些的呢? 本文将尽可能简单的解释Netty中Reactor多线程的实现,如有错误感谢指出. Selector是NIO的重要组件, Selector上可以注册Channel. Channel在注册的时候会标注自己感兴趣的事件: Channel,通道,为了便于理解,我把它分为 三类 Reactor多线程模型可以分为三块 mainReactor负责客户端接入 acceptor负责将接入的连接移交给subReactor subReactor负责连接的读写 关键知识: 运行流程图 关键知识: ChannelPipeline的设计思想是 责任链设计模式 ,是由ChannelHandlerContext组成的 双向链表 , ,首尾固定为 HeadContext 和 TailContext ,它们作为哨兵存在.当我们添加一个ChannelHandler到ChannelPipeline时,会先 包装成ChannelHandlerContext 再添加进去. inbound事件传播 客户端向服务端发送消息,这个流向就称为inbound. 消息会从Head开始由左向右传递直到Tail,由Tail进行收尾操作 outbound事件传播 服务端向客户端发送信息,这个流向称为outbound,消息会从Tail开始由右向左传递知道Head,由Head进行收尾操作 异常传递 当某个ChannelHandler操作抛出异常,会从该handler开始向Tail传递.由Tail做收尾操作. 学习Netty,要理解Reactor模型,并把它和Netty的实现结合起来, 我学习Netty的时候就因为这块认识不深刻,浪费了很多时间也没有成效,共勉 https://blog.csdn.net/difffate/article/details/69458588 https://blog.csdn.net/jjzhk/article/details/39553613 https://www.jianshu.com/p/a9b2fec31fd1 https://www.jianshu.com/p/a9d030fec081 https://juejin.im/post/5b4570cce51d451984695a9b https://www.jianshu.com/p/2461535c38f3 https://juejin.im/post/5a126b146fb9a0450c490201

多线程同步时其中一个线程出异常其它线程会不会继续执

没有太理想的方法 比较笨的办法是自己重新封装一次线程类 如下边的方法就是在run方法的最后一行修改一次状态,如果执行到最后那状态就会修改,如果出现异常执行不到最后状态就不修改 public class Dfdsfasdfasdfa { public static void main(String[] args){ MyTask <a href="https://www.baidu.com/s?wd=t1&tn=44039180_cpr&fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1dbPADLrjn4nWDznyn1mhf0IAYqnWm3PW64rj0d0AP8IA3qPjfsn1bkrjKxmLKz0ZNzUjdCIZwsrBtEXh9GuA7EQhF9pywdQhPEUiqkIyN1IA-EUBtdPjckrjTzrj0" target="_blank" class="baidu-highlight">t1</a> = new MyTask("1"); MyTask <a href="https://www.baidu.com/s?wd=t2&tn=44039180_cpr&fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1dbPADLrjn4nWDznyn1mhf0IAYqnWm3PW64rj0d0AP8IA3qPjfsn1bkrjKxmLKz0ZNzUjdCIZwsrBtEXh9GuA7EQhF9pywdQhPEUiqkIyN1IA-EUBtdPjckrjTzrj0" target="_blank" class="baidu-highlight">t2</a> = new MyTask("s"); <a href="https://www.baidu.com/s?wd=t1&tn=44039180_cpr&fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1dbPADLrjn4nWDznyn1mhf0IAYqnWm3PW64rj0d0AP8IA3qPjfsn1bkrjKxmLKz0ZNzUjdCIZwsrBtEXh9GuA7EQhF9pywdQhPEUiqkIyN1IA-EUBtdPjckrjTzrj0" target="_blank" class="baidu-highlight">t1</a>.start(); <a href="https://www.baidu.com/s?wd=t2&tn=44039180_cpr&fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1dbPADLrjn4nWDznyn1mhf0IAYqnWm3PW64rj0d0AP8IA3qPjfsn1bkrjKxmLKz0ZNzUjdCIZwsrBtEXh9GuA7EQhF9pywdQhPEUiqkIyN1IA-EUBtdPjckrjTzrj0" target="_blank" class="baidu-highlight">t2</a>.start(); try{ <a href="https://www.baidu.com/s?wd=t1&tn=44039180_cpr&fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1dbPADLrjn4nWDznyn1mhf0IAYqnWm3PW64rj0d0AP8IA3qPjfsn1bkrjKxmLKz0ZNzUjdCIZwsrBtEXh9GuA7EQhF9pywdQhPEUiqkIyN1IA-EUBtdPjckrjTzrj0" target="_blank" class="baidu-highlight">t1</a>.join(); <a href="https://www.baidu.com/s?wd=t2&tn=44039180_cpr&fenlei=mv6quAkxTZn0IZRqIHckPjm4nH00T1dbPADLrjn4nWDznyn1mhf0IAYqnWm3PW64rj0d0AP8IA3qPjfsn1bkrjKxmLKz0ZNzUjdCIZwsrBtEXh9GuA7EQhF9pywdQhPEUiqkIyN1IA-EUBtdPjckrjTzrj0" target="_blank" class="baidu-highlight">t2</a>.join(); if(t1.getIsEnd()&&t2.getIsEnd()){ System.out.println("zzzz"); } }catch(InterruptedException e) { } }}class MyTask extends Thread { private String s=null; private boolean isEnd=false; public MyTask(String s){ this.s=s; } public void run() { System.out.println(Integer.parseInt(s)); System.out.println(s); isEnd=true; } public boolean getIsEnd(){ return isEnd; } }

8.Twisted 多线程

在 Twisted 中提供的两种线程: Twisted 中大部分代码都是运行在主线程中,如:dataRecieved、connectionLose 等事件处理函数都是在主线程中被 Twisted 框架调用。这种情况下,如果这些事件处理函数运行的时间较长,则会影响其他事件函数的处理。 在实际开发中,可以将耗时的代码移到辅线程中执行。 在内部,Twisted 很少使用线程。这并不是说它不使用线程。有很多 API 没有等效的非阻塞 API,所以当 Twisted 需要调用它们时,它会在线程中调用它们。 一个常见的错误是认为因为 Twisted 可以同时管理多个连接,所以事情发生在多个线程中,因此您需要小心管理锁。 幸运的是,Twisted 在一个线程中完成了大多数事情! 同时,为了提高运行效率,Twisted 中大多数内置的函数都不是线程安全的,比如:twisted.internet.Protocol().transport.write(),因此需要将内置函数放入主线程中执行,否则可能导致程序逻辑错误,甚至系统崩溃。因此控制代码运行在主线程还是辅线程中是 Twisted 应用开发需要掌握的重要技能。 Twisted 中的所有由框架调用的事件处理函数都运行在主线程中,如果在其他线程中需要执行非线程安全的 Twisted 内置函数,则可以用 reactor.callFromThead() 函数使代码运行在主线程中。 该函数的格式: 该函数将自己的所在的线程在调用处挂起,直到被调用函数在主线程中执行完成。 调用 reactor.callFromThead() 的线程可以是 Twisted 辅线程,也可以是 Twisted 主线程或者是 Python Threading 库等建立的线程。 对于主线程中比较耗时的处理,可以使用 reactor.callInThread() 函数在辅线程中运行。 该函数的格式: Twisted 使用线程池管理所有的辅线程,可以使用 reactor.suggestThreadPoolsize() 函数定义线程池中的线程数量。该函数格式: 线程数量表示辅线程的最大数量,当线程超过该数量时,这些函数将排队等待前面被调度的函数执行完成后才执行。 在前面的示例中,我们曾经通过 Python Threading 创建了线程来实现定时上报或者定时下发指令等操作,但在子线程操作中,我们没有使用 reactor 的相应函数来让其在主线程中执行,所以,都需要在线程中通过 reactor.callFromThead() 来调用非线程安全函数。 我们以《4.Twisted TCP Socket 编程示例》中的示例2 为例来调整程序,示例2 的内容为: 服务端每隔 10 秒钟随机发送一个指令,客户端根据指令来发送设备使用情况,指令如下: 原示例2 服务端代码: 在上面的代码中,CommandThread 的 run 函数中,下面的代码调用了非线程安全函数,需要做调整。 线程调整如下: 在上面的代码中,我们专门写一个 send 函数来下发指令,在子线程中,通过 reactor.callFromThread() 函数让 send 函数在主线程中执行,因为 send 函数中调用了非线程安全的 Twisted 函数。

Linux 多线程编程(二)2019-08-10

三种专门用于线程同步的机制:POSIX信号量,互斥量和条件变量. 在Linux上信号量API有两组,一组是System V IPC信号量,即PV操作,另外就是POSIX信号量,POSIX信号量的名字都是以sem_开头. phshared参数指定信号量的类型,若其值为0,就表示这个信号量是当前进程的局部信号量,否则该信号量可以在多个进程之间共享.value值指定信号量的初始值,一般与下面的sem_wait函数相对应. 其中比较重要的函数sem_wait函数会以原子操作的方式将信号量的值减一,如果信号量的值为零,则sem_wait将会阻塞,信号量的值可以在sem_init函数中的value初始化;sem_trywait函数是sem_wait的非阻塞版本;sem_post函数将以原子的操作对信号量加一,当信号量的值大于0时,其他正在调用sem_wait等待信号量的线程将被唤醒. 这些函数成功时返回0,失败则返回-1并设置errno. 生产者消费者模型: 生产者对应一个信号量:sem_t producer; 消费者对应一个信号量:sem_t customer; sem_init(&producer,2)----生产者拥有资源,可以工作; sem_init(&customer,0)----消费者没有资源,阻塞; 在访问公共资源前对互斥量设置(加锁),确保同一时间只有一个线程访问数据,在访问完成后再释放(解锁)互斥量. 互斥锁的运行方式:串行访问共享资源; 信号量的运行方式:并行访问共享资源; 互斥量用pthread_mutex_t数据类型表示,在使用互斥量之前,必须使用pthread_mutex_init函数对它进行初始化,注意,使用完毕后需调用pthread_mutex_destroy. pthread_mutex_init用于初始化互斥锁,mutexattr用于指定互斥锁的属性,若为NULL,则表示默认属性。除了用这个函数初始化互斥所外,还可以用如下方式初始化:pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER。 pthread_mutex_destroy用于销毁互斥锁,以释放占用的内核资源,销毁一个已经加锁的互斥锁将导致不可预期的后果。 pthread_mutex_lock以原子操作给一个互斥锁加锁。如果目标互斥锁已经被加锁,则pthread_mutex_lock则被阻塞,直到该互斥锁占有者把它给解锁. pthread_mutex_trylock和pthread_mutex_lock类似,不过它始终立即返回,而不论被操作的互斥锁是否加锁,是pthread_mutex_lock的非阻塞版本.当目标互斥锁未被加锁时,pthread_mutex_trylock进行加锁操作;否则将返回EBUSY错误码。注意:这里讨论的pthread_mutex_lock和pthread_mutex_trylock是针对普通锁而言的,对于其他类型的锁,这两个加锁函数会有不同的行为. pthread_mutex_unlock以原子操作方式给一个互斥锁进行解锁操作。如果此时有其他线程正在等待这个互斥锁,则这些线程中的一个将获得它. 三个打印机轮流打印: 输出结果: 如果说互斥锁是用于同步线程对共享数据的访问的话,那么条件变量就是用于在线程之间同步共享数据的值.条件变量提供了一种线程之间通信的机制:当某个共享数据达到某个值时,唤醒等待这个共享数据的线程. 条件变量会在条件不满足的情况下阻塞线程.且条件变量和互斥量一起使用,允许线程以无竞争的方式等待特定的条件发生. 其中pthread_cond_broadcast函数以广播的形式唤醒所有等待目标条件变量的线程,pthread_cond_signal函数用于唤醒一个等待目标条件变量线程.但有时候我们可能需要唤醒一个固定的线程,可以通过间接的方法实现:定义一个能够唯一标识目标线程的全局变量,在唤醒等待条件变量的线程前先设置该变量为目标线程,然后采用广播的方式唤醒所有等待的线程,这些线程被唤醒之后都检查该变量以判断是否是自己. 采用条件变量+互斥锁实现生产者消费者模型: 运行结果: 阻塞队列+生产者消费者 运行结果:

linux中,多线程互斥锁问题

线程之间是并发运行的,所以锁解除后,各个线程都会继续执行,互不影响

多线程安全问题及各种锁

多线程使用不当会出现资源竞争,比如多个线程同时对一块资源进行修改,就会很容易引发数据错乱和数据安全问题。 示例: 以购票系统为例, 对于多线程出现的这种问题,我们的解决办法就是使用线程同步技术,而常见的就是加锁。 2.1 OSSpinLock 自旋锁 自旋锁等待锁的线程会处于忙等(busy-wait)状态,一直占用着CPU资源。 并且现在已经不安全,可能出现优先级反转的问题。 如果等待锁的优先级较高,它会一直占用着CPU的资源,优先级低的线程就无法释放锁。 在iOS10被苹果废弃。由于已经不再安全, 这里不讨论用法了. 2.2 os_unfair_lock 导入头文件 #import <os/lock.h> 调用 ticketTest 方法 打印结果: 2.3 pthread_mutex 互斥锁 普通用法 导入头文件 #import <pthread.h> 调用 ticketTest 方法 打印结果: mutex 也叫“互斥锁”,等待锁的线程处于休眠状态,不是忙等状态。 上面使用的是 Normal 类型同 OSSpinLock 和 os_unfair_lock 作用一样 递归用法 递归锁在被同一线程重复获取时不会产生死锁 递归类型 PTHREAD_MUTEX_RECURSIVE : 条件用法 2.4 NSLock、NSRecursiveLock NSLock 是对 mutex 普通锁的封装 NSRecursiveLock 是对 mutex 递归锁的封装 调用 ticketTest 方法 打印结果: NSRecursiveLock 用法与 NSLock 的用法一样。 2.5 NSCondition NSCondition 是对 mutex 和 cond 的封装 2.6 NSConditionLock 它是对 NSCondition 的进一步封装,可以设置具体的条件值 2.7 dispatch_queue 直接使用GCD的串行队列,也可以实现线程同步 调用ticketTest方法 打印结果: 2.8 dispatch_semaphore 信号量的初始值可以控制线程并发访问的最大值 初始值为1时,代表同时只允许1条线程访问资源,保证线程的同步 调用otherTest会发现每隔两秒打印5条信息。 2.9 @synchronized 是对mutex的递归锁的封装,源码objc4中的objc-sync.mm文件查看 @synchronized(obj)内部会生成obj对应的递归锁,然后进行加锁解锁操作 本文来自: 旺仔大包子 推荐上篇文章: iOS多线程之NSOperation的使用

请解释多线程事件中lock、monitor以及mutex机制的含义与区别

总线程锁定、数据监控 和 多用户终端执行程序

windows使用什么对象使多线程之间对资源互斥

互斥对象的使用和Event的使用基本是一致的。区别在于,Mutex被称为全局互斥对象,不仅可以在多线程中使用,甚至还可以在多进程中使用。Mutex是一个命名对象,所有用同一个名字创建的Mutex都会被视为同一个对象。 无论是Mutex还是Event都有同步和互斥两种用法。很多资源因为本身的特性,要求同时只能有一个线程访问,比如vector之类的数据结构,同时有两个线程做插入操作,数据就会出错;代码也是一样,有一些代码本身是不允许在多线程中间同时进入的。这时候就可以用Mutex或者Event来进行互斥。 具体方法是创建一个初值为True(Set)的AutoReset(ManualReset参数为FALSE)的Mutex或者Event,然后每次要访问对应的资源的时候首先WaitForSingleObject,成功Wait到之后,Event或者Mutex会变成False(Unset)的状态,其他线程就无法进入;等到使用结束之后,再SetEvent使Mutex或者Event恢复Set的状态,让其他等待的线程进入。 CriticalSection之类的模块在内部也是使用了Event或者Mutex来完成互斥的。注意需要对每一个互斥的资源或代码使用一个独立的Mutex或者Event。

使用socket编程,实现一个多线程聊天程序,使用9977端口,要求服务端使用两个线程(一个接收,一个输出)

对于通信来说,不存在绝对的服务器和客户端,谁在等待别人来,谁就是服务器,谁主动去联系人,谁就是客户端。所以。你要想客户端接受消息,那在启动客户端的时候,在客户端程序里开始一个提供端口的Socket就可以了。ServerSocket serverSocket = new ServerSocket(5000);while (true) {final Socket socket = serverSocket.accept();new Thread() {Socket mySocket = socket;@Overridepublic void run() {try {System.out.println(mySocket);InputStream is = mySocket.getInputStream();byte[] bytes = new byte[1024];int n = is.read(bytes);System.out.println(new String(bytes, 0, n));OutputStream os = mySocket.getOutputStream();os.write(("server reply at time " + new Date().toString()).getBytes());mySocket.close();} catch (Exception e) {e.printStackTrace();}}}.start();}

windows环境,多线程情况下,C语言向文件写入数据。

.......补充:.......又补充:大约一个正常人都会认为这个公式是正确的:打开 + 写入 > 写入。这说明楼主你是对的。既然有了正确答案,那我们也就不再继续深究了。

“多线程”的原理是什么?

  多线程概述  进程和线程都是操作系统的概念。进程是应用程序的执行实例,每个进程是由私有的虚拟地址空间、代码、数据和其它各种系统资源组成,进程在运行过程中创建的资源随着进程的终止而被销毁,所使用的系统资源在进程终止时被释放或关闭。  线程是进程内部的一个执行单元。系统创建好进程后,实际上就启动执行了该进程的主执行线程,主执行线程以函数地址形式,比如说main或WinMain函数,将程序的启动点提供给Windows系统。主执行线程终止了,进程也就随之终止。  每一个进程至少有一个主执行线程,它无需由用户去主动创建,是由系统自动创建的。用户根据需要在应用程序中创建其它线程,多个线程并发地运行于同一个进程中。每个线程具有自己的堆栈和自己的 CPU 寄存器副本。其他资源(如文件、静态数据和堆内存)由进程中的所有线程共享。所以线程间的通讯非常方便,多线程技术的应用也较为广泛。但是使用这些公共资源的线程必须同步。Win32 提供了几种同步资源的方式,包括信号、临界区、事件和互斥体。  每个进程都有私有的虚拟地址空间,进程的所有线程共享同一地址空间。每个线程被CPU分配一个时间片,一旦被激活,它正常运行直到时间片耗尽并被挂起,此时,操作系统选择另一个线程进行运行。通过时间片轮转,又出于各个时间片很小(20毫秒级),看起来就像多个线程同时在工作。实际上,只有在多处理器系统上才是真正的在可得到的处理器上同时运行多个线程。基于Win32的应用程序可以通过把给定进程分解(或创建)多个线程挖掘潜在的CPU时间,而且还可以加强应用程序,以使用户提高效率,加强反应能力以及进行后台辅助处理。  在Windows操作系统中,Win32应用程序可以在Windows平台上运行多个实例,每个应用程序实例都是一个独立的进程,而一个进程可以由不止一个线程来实现。对于一个进程来说,当应用程序有几个任务要同时运行时,建立多个线程是有用的。如打印时,利用多线程机制实现多线程,就可在需要打印时创建一个负责完成打印功能的打印线程。创建打印线程之后,系统就变成了多线程。当进行打印时,CPU轮换着分配给这两个线程时间片,所以打印和其他功能一起同时在运行,这就充分利用了CPU处理打印工作之外的空闲时间片,并且避免了用户长久地等待打印时间。这就是所谓的由多线程来实现的多任务,在进行打印任务的同时又可以进行别的任务。要说明的一点是,目前大多数的计算机都是单处理器(CPU)的,为了运行所有这些线程,操作系统为每个独立线程安排一些CPU时间,操作系统以轮换方式向线程提供时间片,这就给人一种假象,好象这些线程都在同时运行。由此可见,如果两个非常活跃的线程为了抢夺对CPU的控制权,在线程切换时会消耗很多的CPU资源,反而会降低系统的性能。这一点在多线程编程时应该注意。  Win32 SDK函数支持进行多线程的程序设计,并提供了操作系统原理中的各种同步、互斥和临界区等操作。Visual C++ 6.0中,使用MFC类库也实现了多线程的程序设计,线程被分为工作者线程(Worker Thread)和用户界面线程(User Interface Thread)两大类。前者常用于处理后台任务,执行这些后台任务并不会耽搁用户对应用程序的使用,即用户操作无需等待后台任务的完成。后者常用来独立的处理用户输入和相应用户的事件。其中用户界面线程的特点是拥有单独的消息队列,可以具有自己的窗口界面,能够对用户输入和事件做出响应。在应用程序中,根据用户界面线程具有消息队列这一特点,可以使之循环等待某一事件发生后再进行处理。由于Windows95时抢先式多任务的操作系统,即使一个线程因等待某事件而阻塞,其他线程仍然可以继续执行。

如何在Java多线程下高效利用HttpClient连接同一服务器接口?

您好,提问者: 1、先说长连接吧,如果TCP协议的话长连接可以通过心跳包来实现。 2、推送的话,这个可以弄一个定时器,来控制线程,推送发送完毕,线程stop()。

在 Java 程序中怎么保证多线程的运行安全?

java中,线程安全的解决方法或过程:1.如果对象是immutable,则是线程安全的,例如:String,可以放心使用。2. 如果对象是线程安全的,则放心使用。3.有条件线程安全,对于Vector和Hashtable一般情况下是线程安全的,但是对于某些特殊情况,需要通过额外的synchronized保证线程安全。4.使用synchronized关键字。

spectre怎么设置多线程仿真

简单的说,simulink的仿真时间是按t = 1,2,3,4,5,6这样的序列来的,本身没有任何物理意义。只是,我们在推导方程的时候是默认把时间单位当做秒来写方程。 如果你的方程推导是把它当做hr来写的,那仿真时,t = 1,2,3,4,5自然就表示小时了

在 Java 程序中怎么保证多线程的运行安全?

java 怎么 保证多线程 的 运行安全 ? 线程的 安全 性问题体现在: 1.原子性:一个或者多个操作在CPU执行的过程中不被中断的特性。 2.可见性:一个线程对共享变量的修改,另外一个线程能够立刻看到。 3.有序性:程序执行的顺序按照代码的先后顺序执行。

课程设计题目,多线程编程:医院门诊模拟,想用java实现,求大神指点

驳回原因都是什么

怎样使用OCI编写多线程的ORACLE应用软件

能发张图片吗?

C#爬虫爬虫的多线程如何实现

一个进程,开了一条线程去执行,那么这个线程就是主线程,一般在UI程序中,如果主线程执行CPU密集型的耗时工作(如IO操作),那么就会导致界面处于”假死“状态,直到主线程完成这个耗时的任务,所以,我们需要解决这种假死的问题,以带给用户更好的交互体验,那么就要用到多线程技术,将耗时的工作,交给后台线程执行。

C 语言多线程怎么读文件高效

C语言---多个线程读取文件,其代码如下:#include#include#include#include#include#include #define THREAD_NUM 25typedef struct{undefinedFILE *_fp;int _nThreadId;//第几个线程sem_t *_semLock;}IDD_THREAD_PARAM;void *ThreadFunc(void *args){undefinedchar sLine[100+1];FILE *fpRead = ((IDD_THREAD_PARAM *)args)->_fp;sem_t *semLock = ((IDD_THREAD_PARAM *)args)->_semLock;int nId = ((IDD_THREAD_PARAM *)args)->_nThreadId;sem_wait(semLock);while(!feof(fpRead)){undefinedmemset(sLine,0,sizeof(sLine));fgets(sLine,100,fpRead);fprintf(stderr,"Thread ID-%d:%s",nId,sLine);}sem_post(semLock);}int main(){undefinedpthread_t *pThreads;sem_t semLock;pThreads = (pthread_t *)malloc(THREAD_NUM*sizeof(pthread_t));sem_init(&semLock,0,1);FILE *fp = fopen("test.txt","r");//开始线程循环IDD_THREAD_PARAM param;for(int i=0;i{undefinedmemset(param,0,sizeof(IDD_THREAD_PARAM));param._fp = fp;param._nThreadId = i;param._semLock = &semLock;pthread_create((pThreads+i),NULL,ThreadFunc,param);}for(int i=0;ipthread_join(*(pThreads+i),NULL);free(pThreads);pThreads = NULL;fclose(fp);fp = NULL;return 0;}

mybatis多线程批量插入MySQL报主键冲突

主键是自增的吗?如果是的话,看一下你的数据库引擎是MyISAM还是InnoDB。有可能是引擎是InnoDB的问题

php不支持多线程怎么办

PHP 默认并不支持多线程,要使用多线程需要安装 pthread 扩展,而要安装 pthread 扩展,必须使用 --enable-maintainer-zts 参数重新编译 PHP,这个参数是指定编译 PHP 时使用线程安全方式。推荐:php服务器线程安全多线程是让程序变得不安分的一个因素,在使用多线程之前,首先要考虑线程安全问题:线程安全:线程安全是编程中的术语,指某个函数、函数库在多线程环境中被调用时,能够正确地处理多个线程之间的共享变量,使程序功能正确完成。在传统多线程中,由于多个线程共享变量,所以可能会导致出现如下问题:存在一个全局数组$arr = array("a");;A线程获取数组长度为1;B 线程获取数组长度为1;A 线程 pop 出数组元素 $a = array_pop($arr); $a = "a";;B 线程也 pop 数组元素 $b = array_pop($arr); $a = null;;此时 B 线程内就出现了灵异事件,明明数组长度大于0,或没有 pop 出东西;PHP 实现PHP 实现的线程安全主要是使用 TSRM 机制对 全局变量和静态变量进行了隔离,将全局变量和静态变量 给每个线程都复制了一份,各线程使用的都是主线程的一个备份,从而避免了变量冲突,也就不会出现线程安全问题。PHP 对多线程的封装保证了线程安全,程序员不用考虑对全局变量加各种锁来避免读写冲突了,同时也减少了出错的机会,写出的代码更加安全。但由此导致的是,子线程一旦开始运行,主线程便无法再对子线程运行细节进行调整了,线程一定程度上失去了线程之间通过全局变量进行消息传递的能力。同时 PHP 开启线程安全选项后,使用 TSRM 机制分配和使用变量时也会有额外的损耗,所以在不需要多线程的 PHP 环境中,使用 PHP 的 ZTS (非线程安全) 版本就好。类和方法PHP 将线程 封装成了 Thread 类,线程的创建通过实例化一个线程对象来实现,由于类的封装性,变量的使用只能通过构造函数传入,而线程运算结果也需要通过类变量传出。下面介绍几个常用的 Thread 类方法:run():此方法是一个抽象方法,每个线程都要实现此方法,线程开始运行后,此方法中的代码会自动执行;start():在主线程内调用此方法以开始运行一个线程;join():各个线程相对于主线程都是异步执行,调用此方法会等待线程执行结束;kill():强制线程结束;isRunning():返回线程的运行状态,线程正在执行run()方法的代码时会返回 true;因为线程安全的实现,PHP 的多线程开始运行后,无法再通过共享内存空间通信,线程也无法通过线程间通信复用,所以我认为 PHP 的“线程池”并没有什么意义。扩展内自带的Pool 类是一个对多线程分配管理的类,这里也不再多介绍了。

php多线程怎么实现

PHP默认并不支持多线程,要使用多线程需要安装pthread扩展,而要安装pthread扩展,必须使用--enable-maintainer-zts参数重新编译PHP,这个参数是指定编译PHP时使用线程安全方式。PHP 实现PHP 实现的线程安全主要是使用 TSRM 机制对 全局变量和静态变量进行了隔离,将全局变量和静态变量 给每个线程都复制了一份,各线程使用的都是主线程的一个备份,从而避免了变量冲突,也就不会出现线程安全问题。(推荐学习:PHP视频教程)PHP 对多线程的封装保证了线程安全,程序员不用考虑对全局变量加各种锁来避免读写冲突了,同时也减少了出错的机会,写出的代码更加安全。但由此导致的是,子线程一旦开始运行,主线程便无法再对子线程运行细节进行调整了,线程一定程度上失去了线程之间通过全局变量进行消息传递的能力。同时 PHP 开启线程安全选项后,使用 TSRM 机制分配和使用变量时也会有额外的损耗,所以在不需要多线程的 PHP 环境中,使用 PHP 的 ZTS (非线程安全) 版本就好。实例代码下面是一个线程类,用来请求某一接口。接下来根据它写两个多线程的应用实例:class Request extends Thread { public $url; public $response; public function __construct($url) { $this->url = $url; } public function run() { $this->response = file_get_contents($this->url); }}异步请求将同步的请求拆分为多个线程异步调用,以提升程序的运行效率。$chG = new Request("www.google.com");$chB = new Request("www.baidu.com");$chG ->start();$chB ->start();$chG->join();$chB->join();$gl = $chG->response;$bd = $chB->response;

php怎么多线程

PHP默认并不支持多线程,要使用多线程需要安装pthread扩展,而要安装pthread扩展,必须使用--enable-maintainer-zts参数重新编译PHP,这个参数是指定编译PHP时使用线程安全方式。多线程是让程序变得不安分的一个因素,在使用多线程之前,首先要考虑线程安全问题:线程安全:线程安全是编程中的术语,指某个函数、函数库在多线程环境中被调用时,能够正确地处理多个线程之间的共享变量,使程序功能正确完成。(推荐学习:PHP视频教程)在传统多线程中,由于多个线程共享变量,所以可能会导致出现如下问题:存在一个全局数组$arr = array("a");;A 线程获取数组长度为1;B 线程获取数组长度为1;A 线程 pop 出数组元素 $a = array_pop($arr); $a = "a";;B 线程也 pop 数组元素 $b = array_pop($arr); $a = null;;此时 B 线程内就出现了灵异事件,明明数组长度大于0,或没有 pop 出东西;PHP 实现PHP 实现的线程安全主要是使用 TSRM 机制对 全局变量和静态变量进行了隔离,将全局变量和静态变量 给每个线程都复制了一份,各线程使用的都是主线程的一个备份,从而避免了变量冲突,也就不会出现线程安全问题。PHP 对多线程的封装保证了线程安全,程序员不用考虑对全局变量加各种锁来避免读写冲突了,同时也减少了出错的机会,写出的代码更加安全。但由此导致的是,子线程一旦开始运行,主线程便无法再对子线程运行细节进行调整了,线程一定程度上失去了线程之间通过全局变量进行消息传递的能力。同时 PHP 开启线程安全选项后,使用 TSRM 机制分配和使用变量时也会有额外的损耗,所以在不需要多线程的 PHP 环境中,使用 PHP 的 ZTS (非线程安全) 版本就好。

C++语言编程 程序多线程的问题!

我没有安装VS2010,所以的话尽可能我告诉你怎么改,你反馈结果给我好吗?程序一看好像没问题,但是你要注意细节问题。在main函数中你创建两个线程后,关闭句柄也没有错,但是你注意了,你为什么要删除临界区对象?(DeleteCriticalSection(&SS);)?恰好你的线程要用SS,你又把他删了不就出问题了吗?错误里给出_unock函数出现错误,明显就是说临界区对象不存在或已被销毁了。所以你应该把这句话放在gethar()函数的后面。当两个线程访问完后你按下一个按键,这时才能删除临界区对象。有不明白的欢迎提问。 主要的不是楼下说的什么主线程退出了,而是因为在你的子线程使用临界区对象时发现错误了,原因是你在main中过早的把临界区对象删除了。

linux中多进程程序和多线程程序的区别

IBM有个家伙做了个测试,发现切换线程context的时候,windows比linux快一倍多。进出最快的锁(windows2k的 critical section和linux的pthread_mutex),windows比linux的要快五倍左右。当然这并不是说linux不好,而且在经过实际编程之后,综合来看我觉得linux更适合做high performance server,不过在多线程这个具体的领域内,linux还是稍逊windows一点。这应该是情有可原的,毕竟unix家族都是从多进程过来的,而 windows从头就是多线程的。  如果是UNIX/linux环境,采用多线程没必要。  多线程比多进程性能高?误导!  应该说,多线程比多进程成本低,但性能更低。  在UNIX环境,多进程调度开销比多线程调度开销,没有显著区别,就是说,UNIX进程调度效率是很高的。内存消耗方面,二者只差全局数据区,现在内存都很便宜,服务器内存动辄若干G,根本不是问题。  多进程是立体交通系统,虽然造价高,上坡下坡多耗点油,但是不堵车。  多线程是平面交通系统,造价低,但红绿灯太多,老堵车。  我们现在都开跑车,油(主频)有的是,不怕上坡下坡,就怕堵车。  高性能交易服务器中间件,如TUXEDO,都是主张多进程的。实际测试表明,TUXEDO性能和并发效率是非常高的。TUXEDO是贝尔实验室的,与UNIX同宗,应该是对UNIX理解最为深刻的,他们的意见应该具有很大的参考意义。  多线程的优点:  无需跨进程边界;程序逻辑和控制方式简单; 所有线程可以直接共享内存和变量等; 线程方式消耗的总资源比进程方式好; 多线程缺点:  每个线程与主程序共用地址空间,受限于2GB地址空间;线程之间的同步和加锁控制比较麻烦; 一个线程的崩溃可能影响到整个程序的稳定性; 到达一定的线程数程度后,即使再增加CPU也无法提高性能,例如Windows Server 2003,大约是1500个左右的线程数就快到极限了(线程堆栈设定为1M),如果设定线程堆栈为2M,还达不到1500个线程总数; 线程能够提高的总性能有限,而且线程多了之后,线程本身的调度也是一个麻烦事儿,需要消耗较多的CPU     多进程优点:  每个进程互相独立,不影响主程序的稳定性,子进程崩溃没关系;通过增加CPU,就可以容易扩充性能;可以尽量减少线程加锁/解锁的影响,极大提高性能,就算是线程运行的模块算法效率低也没关系;每个子进程都有2GB地址空间和相关资源,总体能够达到的性能上限非常大多线程缺点:  逻辑控制复杂,需要和主程序交互;需要跨进程边界,如果有大数据量传送,就不太好,适合小数据量传送、密集运算 多进程调度开销比较大; 最好是多进程和多线程结合,即根据实际的需要,每个CPU开启一个子进程,这个子进程开启多线程可以为若干同类型的数据进行处理。当然你也可以利用多线程+多CPU+轮询方式来解决问题……  方法和手段是多样的,关键是自己看起来实现方便有能够满足要求,代价也合适。

MFC多线程安全问题。

解决不了,伤神

关于c++多线程互斥访问lock和unlock的用法

如果是线程,可以使用临界区。这样比较快。CRITICAL_SECTION m_cs;使用前要先初始化InitializeCriticalSection(&m_cs);用晚后要释放DeleteCriticalSection(&m_cs);线程中void Ctest::RecProc( char* cbuf, int nlen ){EnterCriticalSection(&m_cs);udpDataBuf.push_back(cbuf);LeaveCriticalSection(&m_cs);}

多线程如何同步

进程中线程同步的四种常用方式:1、 临界区(CCriticalSection)当多个线程访问一个独占性共享资源时,可以使用临界区对象。拥有临界区的线程可以访问被保护起来的资源或代码段,其他线程若想访问,则被挂起,直到拥有临界区的线程放弃临界区为止。请点击输入图片描述具体应用方式:1、 定义临界区对象CcriticalSection g_CriticalSection;2、 在访问共享资源(代码或变量)之前,先获得临界区对象,g_CriticalSection.Lock()。请点击输入图片描述3、 访问共享资源后,则放弃临界区对象,g_CriticalSection.Unlock(); 2、 事件(CEvent)事件机制,则允许一个线程在处理完一个任务后,主动唤醒另外一个线程执行任务。比如在某些网络应用程序中,一个线程如A负责侦听通信端口,另外一个线程B负责更新用户数据,利用事件机制,则线程A可以通知线程B何时更新用户数据。请点击输入图片描述每个Cevent对象可以有两种状态:有信号状态和无信号状态。Cevent类对象有两种类型:人工事件和自动事件。自动事件对象,在被至少一个线程释放后自动返回到无信号状态。请点击输入图片描述人工事件对象,获得信号后,释放可利用线程,但直到调用成员函数ReSet()才将其设置为无信号状态。请点击输入图片描述

多线程 全局变量 加锁 作用范围

我的理解是每一个线程都有一个独立的对象就不存在线程安全问题,也没有了加锁的必要

delphi多线程互斥,用多线程怎么解决同一时间内调用同一函数

Delphi同步互斥总结 多个线程同时访问一个共享资源或数据时,需要考虑线程同步,Synchronize()是在一个隐蔽的窗口里运行,如果在这里你的任务很繁忙,你的主窗口会阻塞掉;Synchronize()只是将该线程的代码放到主线程中运行,并非线程同步。 临 界区是一个进程里的所有线程同步的最好办法,他不是系统级的,只是进程级的,也就是说他可能利用进程内的一些标志来保证该进程内的线程同步,据 Richter说是一个记数循环;临界区只能在同一进程内使用;临界区只能无限期等待,不过2k增加了TryEnterCriticalSection函 数实现0时间等待。 互斥则是保证多进程间的线程同步,他是利用系统内核对象来保证同步的。由于系统内核对象可以是有名字的,因此多个 进程间可以利用这个有名字的内核对象保证系统资源的线程安全性。互斥量是Win32 内核对象,由操作系统负责管理;互斥量可以使用WaitForSingleObject实现无限等待,0时间等待和任意时间等待。常见的线程同步方法如下:1. 临界区临界区是一种最直接的线程同步方式。所谓临界区,就是一次只能由一个线程来执行的一段代码。如果把初始化数组的代码放在临界区内,另一个线程在第一个线程处理完之前是不会被执行的。使用方法如下://在窗体创建中InitializeCriticalSection(Critical1)//在窗体销毁中DeleteCriticalSection(Critical1)//在线程中EnterCriticalSection(Critical1)……保护的代码LeaveCriticalSection(Critical1)2. 互斥互斥非常类似于临界区,除了两个关键的区别:首先,互斥可用于跨进程的线程同步。其次,互斥能被赋予一个字符串名字,并且通过引用此名字创建现有互斥对象的附加句柄。 临界区与事件对象(比如互斥对象)的最大的区别是在性能上。临界区在没有线程冲突时,要用10 ~ 15个时间片,而事件对象由于涉及到系统内核要用400~600个时间片。Mutex(互斥对象),是用于串行化访问资源的全局对象。我们首先设置互斥对象,然后访问资源,最后释放互斥对象。在设置互斥对象时,如果另一个线程(或进程)试图设置相同的互斥对象,该线程将会停下来,直到前一个线程(或进程)释放该互斥对象为止。注意它可以由不同应用程序共享。使用方法如下://在窗体创建中hMutex:=CreateMutex(nil,false,nil)//在窗体销毁中CloseHandle(hMutex)//在线程中WaitForSingleObject(hMutex,INFINITE)……保护的代码ReleaseMutex(hMutex)3. 信号量另一种使线程同步的技术是使用信号量对象。它是在互斥的基础上建立的,但信号量增加了资源计数的功能,预定数目的线程允许同时进入要同步的代码。可以用CreateSemaphore()来创建一个信号量对象,因为只允许一个线程进入要同步的代码,所以信号量的最大计数值(lMaximumCount)要设为1。其实Mutex就是最大计数为一的Semaphore。使用方法如下://在窗体创建中hSemaphore:= CreateSemaphore(nil,lInitialCount,lMaximumCount,lpName)//在窗体销毁中CloseHandle(hSemaphore)//在线程中WaitForSingleObject(hSemaphore,INFINITE)……保护的代码ReleaseSemaphore(hSemaphore, lReleaseCount, lpPreviousCount)4.WaitForSingleObject函数的返值:WAIT_ABANDONED指定的对象是互斥对象,并且拥有这个互斥对象的线程在没有释放此对象之前就已终止。此时就称互斥对象被抛弃。这种情况下,这个互斥对象归当前线程所有,并把它设为非发信号状态;WAIT_OBJECT_0 指定的对象处于发信号状态;WAIT_TIMEOUT等待的时间已过,对象仍然是非发信号状态;Delphi 常用的临界区对象TCriticalSection(Delphi) 、TRtlCriticalSectionTRtlCriticalSection 是一个结构体,在windows单元中定义; 是InitializeCriticalSection,EnterCriticalSection,LeaveCriticalSection, DeleteCriticalSection 等这几个kernel32.dll中的临界区操作API的参数;TCriticalSection是在SyncObjs单元中实现的类,它对上面的那些临界区操作API函数进行了了封装,简化并方便了在Delphi的使用;如TCriticalSection.Create,TCriticalSection.Enter, TcriticalSection.Leave等;通过调用上面响应的API函数实现。线程同步的多种办法中,使用临界区最简单,也是效率最高的办法(CPU占用时间最少)使用临界区代码如下:先声明一个TRTLCriticalSection类型的全局变量varMyCs:TRTLCriticalSection;在程序开始或建立线程之前,初始化InitializeCriticalSection(MyCs);//初始化临界区在程序结束或所有线程结束后,删除它DeleteCriticalSection(MyCs);//删除临界区再在线程中要同步的地方加入EnterCriticalSection(MyCs); //进入临界区try//程序代码finallyLeaveCriticalSection(MyCs); //离开临界区end;补充今天遇到的关于Application.ProcessMessages同步的问题:有一个函数Fn按执行顺序可分为A->B->C3大块,其中B块有要绘制各种窗口界面的操作很复杂且耗时较长,并且里面用到了Application.ProcessMessages,程序运行测试时发现如果在Fn执行B绘制窗口的过程没结束时又调用Fn函数去绘制其它窗口就可能会导致程序崩溃,一开始尝试用TcriticalSection变量解决,完全没用,最后用增加一个全局变量的方法解决:定义一个全局Boolean型变量flag,设定初始值为True,改造Fn函数的逻辑为A-> if flag thenBeginFlag:=False;B;Flag:=True;End;->C问题成功解决。顺便总结Application.ProcessMessages的作用:运行一个非常耗时的循环,那么在这个循环结束前,程序可能不会响应任何事件,按钮没有反应,程序设置无法绘制窗体,看上去就如同死了一样,这有时不是很方便,例如于终止循环的机会都没有了,又不想使用多线程时,这时你就可以在循环中加上这么一句,每次程序运行到这句时,程序就会让系统响应一下消息,从而使你有机会按按钮,窗体有机会绘制。所起作用类似于VB中DoEvent方法.调用ProcessMessages来使应用程序处于消息队列能够进行消息处理,ProcessMessages将Windows消息进行循环轮转,直至消息为空,然后将控制返回给应用程序。注示:仅在应用程序调用ProcessMessages时勿略消息进程效果,而并非在其他应用程序中。在冗长的操作中,调用ProcessMessages周期性使得应用程序对画笔或其他信息产生回应。ProcessMessages不充许应该程序空闲,而HandleMessage则然.使用ProcessMessages一定要保证相关代码是可重入的,如果实在不行也可按我上面的方法实现同步。

c++多线程问题

  当多个线程访问一个独占性共享资源时,可以使用“临界区”对象。任一时刻只有一个线程可以拥有临界区对象,拥有临界区的线程可以访问被保护起来的资源或代码段,其他希望进入临界区的线程将被挂起等待,直到拥有临界区的线程放弃临界区时为止,这样就保证了不会在同一时刻出现多个线程访问共享资源。CCriticalSection类的用法非常简单,步骤如下:  定义CCriticalSection类的一个全局对象(以使各个线程均能访问),如CCriticalSection critical_section; 在访问需要保护的资源或代码之前,调用CCriticalSection类的成员Lock()获得临界区对象: critical_section.Lock();在线程中调用该函数来使线程获得它所请求的临界区。如果此时没有其它线程占有临界区对象,则调用Lock()的线程获得临界区;否则,线程将被挂起,并放入到一个系统队列中等待,直到当前拥有临界区的线程释放了临界区时为止。 访问临界区完毕后,使用CCriticalSection的成员函数Unlock()来释放临界区:critical_section.Unlock();再通俗一点讲,就是线程A执行到critical_section.Lock();语句时,如果其它线程(B)正在执行critical_section.Lock();语句后且critical_section. Unlock();语句前的语句时,线程A就会等待,直到线程B执行完critical_section. Unlock();语句,线程A才会继续执行。

29、C#的多线程Task的使用

简单总结:有async Task修饰的方法,方法里面必然有await的调用或者有Task相关的效用。在外部可以直接调用async修饰的方法。在Addressables中大量使用了Task的异步操作,所以也可以使用await来让异步操作以等待的方式运行, await能让Addressables的使用更加方便,少了很多回调相关逻辑的编写。 可以参照: https://www.jianshu.com/p/dfa98f540673 参考: https://www.cnblogs.com/zhaoshujie/p/11082753.html https://blog.csdn.net/kingBook928/article/details/104958881?spm=1001.2101.3001.6650.1&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-1.pc_relevant_default&utm_relevant_index=2

经验分享:对Java中的线程感想(多线程)

1.进程和线程的区别   通俗一点说,进程就是程序的一次执行,而线程可以理解为进程中的执行的一段程序片段。   用一点文词说就是,每个进程都有独立的代码和数据空间(进程上下文);而线程可以看成是轻量级的进程。一般来讲(不使用特殊技术),同一进程所产生的线程共享同一块内存空间。   同一进程中的两段代码是不可能同时执行的,除非引入线程。   线程是属于进程的,当进程退出时该进程所产生的线程都会被强制退出并清除。   线程占用的资源要少于进程所占用的资源。   进程和线程都可以有优先级。   在线程系统中进程也是一个线程。可以将进程理解为一个程序的第一个线程。   多进程——在操作系统中,能同时运行多个任务(程序)。   多线程——在同一应用程序中,有多个顺序流同时执行。   2.通过铁路售票程序来理解实现多线程的两种方法:通过java.lang.Thread类和通过Runnable接口   java中有两种实现多线程的方式。一是直接继承Thread类,二是实现Runnable接口。那么这两种实现多线程的方式在应用上有什么区别呢?   为了回答这个问题,我们可以通过编写一段代码来进行分析。我们用代码来模拟铁路售票系统,实现通过四个售票点发售某日某次列车的100张车票,一个售票点用一个线程表示。   我们首先这样编写这个程序:   public class ThreadDome1{   public static void main(String[] args){   ThreadTest t = new ThreadTest();   t.start();   t.start();   t.start();   t.start();   }   }   class ThreadTest extends Thread{   private int ticket = 100;   public void run(){   while(true){   if(ticket > 0){   System.out.println(Thread.currentThread().getName() +   "is saling ticket" + ticket--);   }else{   break;   }   }   }   }   上面的代码中,我们用ThreadTest类模拟售票处的售票过程,run方法中的每一次循环都将总票数减1,模拟卖出一张车票,同时该车票号打印出来,直接剩余的票数到零为止。在ThreadDemo1类的main方法中,我们创建了一个线程对象,并重复启动四次,希望通过这种方式产生四个线程。从运行的结果来看我们发现其实只有一个线程在运行,这个结果告诉我们:一个线程对象只能启动一个线程,无论你调用多少遍start()方法,结果只有一个线程。   我们接着修改ThreadDemo1,在main方法中创建四个Thread对象:   public class ThreadDemo1{   public static void main(String[] args){   new ThreadTest().start();   new ThreadTest().start();   new ThreadTest().start();   new ThreadTest().start();   }   }   class ThreadTest extends Thread{   private int ticket = 100;   public void run(){   while(true){   if(ticket > 0){   System.out.println(Thread.currentThread().getName() +   " is saling ticket" + ticket--);   }else{   break;   }   }   }   }   这下达到目的了吗?   从结果上看每个票号都被打印了四次,即四个线程各自卖各自的100张票,而不去卖共同的100张票。这种情况是怎么造成的呢?我们需要的是,多个线程去处理同一个资源,一个资源只能对应一个对象,在上面的程序中,我们创建了四个ThreadTest对象,就等于创建了四个资源,每个资源都有100张票,每个线程都在独自处理各自的资源。   经过这些实验和分析,可以总结出,要实现这个铁路售票程序,我们只能创建一个资源对象,但要创建多个线程去处理同一个资源对象,并且每个线程上所运行的是相同的程序代码。在回顾一下使用接口编写多线程的过程。   public class ThreadDemo1{   public static void main(String[] args){   ThreadTest t = new ThreadTest();   new Thread(t).start();   new Thread(t).start();   new Thread(t).start();   new Thread(t).start();   }   }   class ThreadTest implements Runnable{   private int tickets = 100;   public void run(){   while(true){   if(tickets > 0){   System.out.println(Thread.currentThread().getName() +   " is saling ticket " + tickets--);   }   }   }   }   上面的程序中,创建了四个线程,每个线程调用的是同一个ThreadTest对象中的run()方法,访问的是同一个对象中的变量(tickets)的实例,这个程序满足了我们的需求。在Windows上可以启动多个记事本程序一样,也就是多个进程使用同一个记事本程序代码。   可见,实现Runnable接口相对于继承Thread类来说,有如下显著的好处:   (1)适合多个相同程序代码的线程去处理同一资源的情况,把虚拟CPU(线程)同程序的代码,数据有效的分离,较好地体现了面向对象的设计思想。   (2)可以避免由于Java的单继承特性带来的局限。我们经常碰到这样一种情况,即当我们要将已经继承了某一个类的子类放入多线程中,由于一个类不能同时有两个父类,所以不能用继承Thread类的方式,那么,这个类就只能采用实现Runnable接口的方式了。   (3)有利于程序的健壮性,代码能够被多个线程共享,代码与数据是独立的。当多个线程的执行代码来自同一个类的实例时,即称它们共享相同的代码。多个线程操作相同的数据,与它们的代码无关。当共享访问相同的对象时,即它们共享相同的数据。当线程被构造时,需要的代码和数据通过一个对象作为构造函数实参传递进去,这个对象就是一个实现了Runnable接口的类的实例。

CPU的多线程可以关闭吗?

不可以线程就像核心,是固有的,不能关掉

为什么在多核多线程程序中要慎用volatile关键字

a. 避免用通用寄存器对内存读写的优化。编译器常做的一种优化就是:把常用变量的频繁读写弄到通用寄存器中,最后不用的时候再存回内存中。但是如果某个内存地址中的值是由片外决定的(例如另一个线程或是另一个设备可能更改它),那就需要volatile关键字了。(感谢Kenny老师指正)b.硬件寄存器可能被其他设备改变的情况。例如一个嵌入式板子上的某个寄存器直接与一个测试仪器连在一起,这样在这个寄存器的值随时可能被那个测试仪器更改。在这种情况下如果把该值设为volatile属性的,那么编译器就会每次都直接从内存中去取这个值的最新值,而不是自作聪明的把这个值保留在缓存中而导致读不到最新的那个被其他设备写入的新值。c. 同一个物理内存地址M有两个不同的内存地址的情况。例如两个程序同时对同一个物理地址进行读写,那么编译器就不能假设这个地址只会有一个程序访问而做缓存优化,所以程序员在这种情况下也需要把它定义为volatile的。

为什么在多线程程序中要慎用volatile关键字

  因为volatile并不能保证其原子性,他只保证了某一个线程对他修改以后其他线程可见,  尤其是当多个线程对一个变量自增活自减时会导致变量出错。  参照《深入理解java虚拟机》一书,volatile运用在以下场景:  1>运算结果并不依赖变量的当前值,或者能够确保只有单一的线程修改变量的值。  2>变量不需要与其他的状态变量共同参与不变约束(表示看不懂这句)。  因此,在使用volatile关键字时要慎重,并不是只要简单类型变量使用volatile修饰,对这个变量的所有操作都是原来操作,当变量的值由自身的 上一个决定时,如n=n+1、n++等,volatile关键字将失效,只有当变量的值和自身上一个值无关时对该变量的操作才是原子级别的,如n = m+1,这个就是原级别的。所以在使用volatile关键时一定要谨慎,如果自己没有把握,可以使用synchronized来代替volatile。

用C++进行多线程有没有必要加volatile么?

可以说volatile这个关键字并不是多线程专有的,很多嵌入式开发里都会有。主要控制的就是当修改变量时系统仅是改了临时存放变量的寄存器而没有及时更改相应内存,这会导致这段空窗期的其他程序读取这个内存数据时是过时的,或者说就是错误的。很多嵌入式开发中,都会有这样的问题,外部IO口的变化会使系统内部某变量改变,但是不用这个关键字可能会导致非常严重的控制错误。比如电梯运行中的平层信号,如果没有及时写入内存,将会使系统读取一个错误的楼层数据,结果是灾难性的。多线程中,这个关键字的作用类同,都是出于同步控制的考量。总之volatile和多线程没有关系volatile和多线程没有关系volatile和多线程没有关系,重要的事情说三遍。加了volatile不会让错误的程序变正确,去掉volatile也不会让正确的程序变错误。如果你愿意大可以加上这个东西,反正它除了让你的程序变慢一点之外不会有其它影响。

多线程编程中什么情况下需要加 volatile

C/C++多线程编程中不要使用volatile。(注:这里的意思指的是指望volatile解决多线程竞争问题是有很大风险的,除非所用的环境系统不可靠才会为了保险加上volatile,或者是从极限效率考虑来实现很底层的接口。这要求编写者对程序逻辑走向很清楚才行,不然就会出错)C++11标准中明确指出解决多线程的数据竞争问题应该使用原子操作或者互斥锁。C和C++中的volatile并不是用来解决多线程竞争问题的,而是用来修饰一些因为程序不可控因素导致变化的变量,比如访问底层硬件设备的变量,以提醒编译器不要对该变量的访问擅自进行优化。简单的来说,对访问共享数据的代码块加锁,已经足够保证数据访问的同步性,再加volatile完全是多此一举。如果光对共享变量使用volatile修饰而在可能存在竞争的操作中不加锁或使用原子操作对解决多线程竞争没有任何卵用,因为volatile并不能保证操作的原子性,在读取、写入变量的过程中仍然可能被其他线程打断导致意外结果发生。

为什么在多核多线程程序中要慎用volatile关键字

1、避免用通用寄存器对内存读写的优化。编译器常做的一种优化就是:把常用变量的频繁读写弄到通用寄存器中,最后不用的时候再存回内存中。但是如果某个内存地址中的值是由片外决定的(例如另一个线程或是另一个设备可能更改它),那就需要volatile关键字了。(感谢Kenny老师指正)2、硬件寄存器可能被其他设备改变的情况。例如一个嵌入式板子上的某个寄存器直接与一个测试仪器连在一起,这样在这个寄存器的值随时可能被那个测试仪器更改。在这种情况下如果把该值设为volatile属性的,那么编译器就会每次都直接从内存中去取这个值的最新值,而不是自作聪明的把这个值保留在缓存中而导致读不到最新的那个被其他设备写入的新值。3、同一个物理内存地址M有两个不同的内存地址的情况。例如两个程序同时对同一个物理地址进行读写,那么编译器就不能假设这个地址只会有一个程序访问而做缓存优化,所以程序员在这种情况下也需要把它定义为volatile的。

Linux下多线程和多进程程序的优缺点,各个适合什么样的业务场景

  IBM有个家伙做了个测试,发现切换线程context的时候,windows比linux快一倍多。进出最快的锁(windows2k的 critical section和linux的pthread_mutex),windows比linux的要快五倍左右。当然这并不是说linux不好,而且在经过实际编程之后,综合来看我觉得linux更适合做high performance server,不过在多线程这个具体的领域内,linux还是稍逊windows一点。这应该是情有可原的,毕竟unix家族都是从多进程过来的,而 windows从头就是多线程的。  如果是UNIX/linux环境,采用多线程没必要。  多线程比多进程性能高?误导!  应该说,多线程比多进程成本低,但性能更低。  在UNIX环境,多进程调度开销比多线程调度开销,没有显著区别,就是说,UNIX进程调度效率是很高的。内存消耗方面,二者只差全局数据区,现在内存都很便宜,服务器内存动辄若干G,根本不是问题。  多进程是立体交通系统,虽然造价高,上坡下坡多耗点油,但是不堵车。  多线程是平面交通系统,造价低,但红绿灯太多,老堵车。  我们现在都开跑车,油(主频)有的是,不怕上坡下坡,就怕堵车。  高性能交易服务器中间件,如TUXEDO,都是主张多进程的。实际测试表明,TUXEDO性能和并发效率是非常高的。TUXEDO是贝尔实验室的,与UNIX同宗,应该是对UNIX理解最为深刻的,他们的意见应该具有很大的参考意义。  多线程的优点:  无需跨进程边界;程序逻辑和控制方式简单; 所有线程可以直接共享内存和变量等; 线程方式消耗的总资源比进程方式好; 多线程缺点:  每个线程与主程序共用地址空间,受限于2GB地址空间;线程之间的同步和加锁控制比较麻烦; 一个线程的崩溃可能影响到整个程序的稳定性; 到达一定的线程数程度后,即使再增加CPU也无法提高性能,例如Windows Server 2003,大约是1500个左右的线程数就快到极限了(线程堆栈设定为1M),如果设定线程堆栈为2M,还达不到1500个线程总数; 线程能够提高的总性能有限,而且线程多了之后,线程本身的调度也是一个麻烦事儿,需要消耗较多的CPU     多进程优点:  每个进程互相独立,不影响主程序的稳定性,子进程崩溃没关系;通过增加CPU,就可以容易扩充性能;可以尽量减少线程加锁/解锁的影响,极大提高性能,就算是线程运行的模块算法效率低也没关系;每个子进程都有2GB地址空间和相关资源,总体能够达到的性能上限非常大多线程缺点:  逻辑控制复杂,需要和主程序交互;需要跨进程边界,如果有大数据量传送,就不太好,适合小数据量传送、密集运算 多进程调度开销比较大; 最好是多进程和多线程结合,即根据实际的需要,每个CPU开启一个子进程,这个子进程开启多线程可以为若干同类型的数据进行处理。当然你也可以利用多线程+多CPU+轮询方式来解决问题……  方法和手段是多样的,关键是自己看起来实现方便有能够满足要求,代价也合适。  

关于普通类的指针作为结构体的一个成员变量,然后将这个结构体作为参数传递给多线程的问题

特点有很多,简单易上手是比较明显的编程方式。。。你指什么?主要应用:网络,WEB开发简单,但是依然有它需要长时间研究的地方IDE:VS系列,2003,2005,2008等可以游戏开发,理论上是都能做的

JAVA:利用多线程技术编写程序,其中包含滚动字符串,从左向右移动

楼主说得太模糊了,完全搞不清楚究竟要干什么楼上也晕了一点吧楼主问的是java,又不使用js的网页开发

请问大神Hyper-V如何搭建多核多线程处理器的虚拟机

为新部署的微软Hyper-V环境中的主机和网络挑选合适的硬件并非易事,更不用说在生产环境中衡量和监控性能这项任务了。在本文中,我将剖析组成Hyper-V底层硬件架构的不同部件,先从处理器的配置开始说起,之后会介绍内存、存储和网络等子系统。然后我们会深入介绍提升性能的方法和技巧、如何选择合适的Hyper-V版本、配置方面的常见问题,最后介绍虚拟机的性能监控以及这与物理环境监控有何不同之处。注意:所有建议都适用于Windows Server 2008 R2(含服务包1)中的Hyper-V。就可扩展性方面的局限而言,即将推出的Windows Server 8中新的Hyper-V版本有了很大的改进,但是这不是本文探讨的话题。这里给出的建议只适用于最新的Windows版本。虚拟处理器和逻辑处理器我接触的IT管理员对于虚拟处理器和逻辑处理器是什么,它们对于某一个物理主机上虚拟机的最大数量有何影响经常存在一种误解。这不仅与分配给虚拟机的处理器数量有关,还与每个主机的物理内存数量直接有关(下一回会介绍)。逻辑处理器是多核处理器的一个核心,所以一个四核处理器有四个逻辑处理器。如果该四核处理器有超线程(Hyper Threading)技术,它会显示为八个核心;这意味着,你的系统有八个逻辑处理器。尽管微软的说明文档这么介绍逻辑处理器,但是要注意:超线程并不会神奇地让处理器容量翻番。为了稳妥起见,就看核心算作逻辑处理器——如果你启用了超线程技术,其数量也不会翻番。虚拟处理器是你分配给一个个虚拟机的资源;你能分配多少个虚拟处理器,取决于访客/虚拟机操作系统。在这里,操作系统版本越新,功能就越强;所以Windows 2008/2008 R2能与四个虚拟处理器协同运行,而Windows Server 2003只能被分配一两个虚拟处理器。SuSE Linux企业版、CentOS和红帽企业版Linux(它们都是得到支持的操作系统版本)最多可以被分配四个虚拟处理器。如果你在虚拟桌面基础架构(VDI)环境中运行客户机操作系统,Windows 7最多可以与四个虚拟处理器协同运行,Vista能看到两个虚拟处理器,Windows XP SP3能看到两个虚拟处理器。就因为你为某一个虚拟机分配了两个或四个虚拟处理器,并不是说你应该这么做。首先,由于跨处理器的通信,在任何多处理器系统中存在一定的开销——无论是物理处理器还是虚拟处理器。但是在较新的操作系统中开销比较低,所以Windows 2008 R2虚拟机使用四个虚拟处理器没什么问题,而Windows Server 2003可能需要进行测试,看看在你的特定环境下使用两个虚拟处理器有没有好处。其次,这完全取决于工作负载——有些应用程序是密集的多线程(想一想SQL Server等类似应用),使用几个虚拟处理器比较好;而单线程应用程序或者只有几个线程的应用程序得到的好处并不大。另一个常见的误解是,为虚拟机分配一个或多个虚拟处理器与物理核心有关系。为虚拟机分配虚拟处理器其实更像为虚拟机分配一段预定的处理器时间,而虚拟机管理程序实际上把运行虚拟机的负担分摊到所有可用的处理器核心上。分配给某一个主机上多个虚拟机的虚拟处理器数量与微软的这个建议密切相关:一个系统中每个逻辑处理器的虚拟处理器至少是4个,每个逻辑处理器的虚拟处理器最多是8个。例外情况是:如果你在VDI环境下是清一色的Windows 7虚拟机,支持的最大比率是12;也就是说每个逻辑处理器的虚拟处理器最多可以是12个。如果你有配备2个四核处理器(即八个逻辑处理器)的Hyper-V主机,那么运行8个虚拟机完全没问题,每个虚拟机有4个虚拟处理器(共32个虚拟处理器)和最多16个虚拟机(共64个虚拟处理器)。如果你为每个虚拟机只分配了两个虚拟处理器,那么在每个虚拟机一模一样的这个例子中把那些数量提高一倍。当然,在实际情况下,不同虚拟机中虚拟处理器的数量会有所不同,具体看里面运行的工作负载。想查看你主机上虚拟处理器与逻辑处理器的比率,你可以手动查看每一个运行的虚拟机,然后累计被分配的虚拟处理器的总数,这个方法不是很方便。更好的办法就是运行这个简单的PowerShell cmdlet命令,它会给出答案:write-host (@(gwmi -ns rootvirtualization MSVM_Processor).count / (@(gwmiWin32_Processor) | measure -p NumberOfLogicalProcessors -sum).Sum) "virtualprocessor(s) per logical processor" -f yellow多谢微软的虚拟化项目经理Ben Armstrong给出了这个方法。表明了我启用了超线程技术的四核笔记本电脑上的数值(共8个逻辑处理器),有4个虚拟机在运行,每个虚拟机有4个虚拟处理器。:使用这个简单的cmdlet命令,很容易搞清楚Hyper-V主机上虚拟处理器与逻辑处理器的比率。了解你在每个虚拟机上要运行的工作负载和应用程序,这点也很重要:它们是不是受处理器的限制还是受内存的限制?它们是否得益于多线程,因而是否得益于额外的虚拟处理器?确保你购买的处理器支持二级地址转换(SLAT),英特尔称之为扩展页表(EPT),AMD则称之为快速虚拟化索引(RVI),AMD早期的说明文档称之为嵌套页表(NPT)。比较旧的处理器不支持SLAT,这意味着每个虚拟机将多占用10MB至30MB的内存,处理器占用率将增加10%或更多。SLAT可以带来显著的效益,具体视工作负载而定。如果你对远程桌面服务(Remote Desktop Services)进行虚拟化处理,可能会看到SLAT处理器支持的会话数量最多增加40%。搭载大容量二级缓存和三级缓存的处理器也有助于处理要求大量内存的工作负载。图2:为虚拟机分配虚拟处理器很容易;只要从列表中进行选择即可。最后,如果你有一个主机,但处理器资源有限,那么你只要使用虚拟机预留设置和虚拟机限额设置,就可以改变诸虚拟机之间的平衡关系;虚拟机预留设置确保了虚拟机总是可以使用这个数量的处理器资源(但限制了可以在主机上运行的虚拟机总数),虚拟机限额设置控制着虚拟机可以使用多少被分配的处理器容量,Relative weight(相对权重)将该虚拟机与其他运行的虚拟机作一平衡;如果这个值比较低,意味着它在竞争时间段获得的资源会比较少。微软的建议是,除非你有充足的理由要改动,否则别去改动这些设置。还有处理器兼容性设置,让你可以在拥有不同年代处理器的主机之间迁移虚拟机,还让你可以运行版本很老的操作系统,比如Windows NT。

C# winform 多线程

把多线程用法好好看看。上面代码明显有误 。

c#多线程中控件的Invoke()中参数为什么不能直接传一个方法也不能传一个Lamda函数而要用newAction这种方式

你都已经用匿名委托用 => 了,这不是 Lambda 是啥!Invoke() 方法参数是一个委托类型,要是不用匿名委托的话,你得定义一个 delegate 类型对象传进去。

C#多线程处理DataRow时报错

while (true) 在搞鬼,你的这个死循环有什么用呢?

c#多线程有几种实现方法

这篇文章主要介绍了c#使用多线程的几种方式,通过示例学习c#的多线程使用方式,大家参考使用吧(1)不需要传递参数,也不需要返回参数ThreadStart是一个委托,这个委托的定义为void ThreadStart(),没有参数与返回值。复制代码 代码如下:class Program{static void Main(string[] args){for (int i = 0; i < 30; i++){ThreadStart threadStart = new ThreadStart(Calculate);Thread thread = new Thread(threadStart);thread.Start();}Thread.Sleep(2000);Console.Read();}public static void Calculate(){DateTime time = DateTime.Now;//得到当前时间Random ra = new Random();//随机数对象Thread.Sleep(ra.Next(10,100));//随机休眠一段时间Console.WriteLine(time.Minute + ":" + time.Millisecond);}}(2)需要传递单个参数ParameterThreadStart委托定义为void ParameterizedThreadStart(object state),有一个参数但是没有返回值。复制代码 代码如下:class Program{static void Main(string[] args){for (int i = 0; i < 30; i++){ParameterizedThreadStart tStart = new ParameterizedThreadStart(Calculate);Thread thread = new Thread(tStart);thread.Start(i*10+10);//传递参数}Thread.Sleep(2000);Console.Read();}public static void Calculate(object arg){Random ra = new Random();//随机数对象Thread.Sleep(ra.Next(10, 100));//随机休眠一段时间Console.WriteLine(arg);}}(3)使用专门的线程类(常用)使用线程类可以有多个参数与多个返回值,十分灵活!复制代码 代码如下:class Program{static void Main(string[] args){MyThread mt = new MyThread(100);ThreadStart threadStart = new ThreadStart(mt.Calculate);Thread thread = new Thread(threadStart);thread.Start();//等待线程结束while (thread.ThreadState != ThreadState.Stopped){Thread.Sleep(10);}Console.WriteLine(mt.Result);//打印返回值Console.Read();}}public class MyThread//线程类{public int Parame { set; get; }//参数public int Result { set; get; }//返回值//构造函数public MyThread(int parame){this.Parame = parame;}//线程执行方法public void Calculate(){Random ra = new Random();//随机数对象Thread.Sleep(ra.Next(10, 100));//随机休眠一段时间Console.WriteLine(this.Parame);this.Result = this.Parame * ra.Next(10, 100);}}(4)使用匿名方法(常用)使用匿名方法启动线程可以有多个参数和返回值,而且使用非常方便!复制代码 代码如下:class Program{static void Main(string[] args){int Parame = 100;//当做参数int Result = 0;//当做返回值//匿名方法ThreadStart threadStart = new ThreadStart(delegate(){Random ra = new Random();//随机数对象Thread.Sleep(ra.Next(10, 100));//随机休眠一段时间Console.WriteLine(Parame);//输出参数Result = Parame * ra.Next(10, 100);//计算返回值});Thread thread = new Thread(threadStart);thread.Start();//多线程启动匿名方法//等待线程结束while (thread.ThreadState != ThreadState.Stopped){Thread.Sleep(10);}Console.WriteLine(Result);//打印返回值Console.Read();}}(5)使用委托开启多线程(多线程深入)1、用委托(Delegate)的BeginInvoke和EndInvoke方法操作线程BeginInvoke方法可以使用线程异步地执行委托所指向的方法。然后通过EndInvoke方法获得方法的返回值(EndInvoke方法的返回值就是被调用方法的返回值),或是确定方法已经被成功调用。复制代码 代码如下:class Program{private delegate int NewTaskDelegate(int ms);private static int newTask(int ms){Console.WriteLine("任务开始");Thread.Sleep(ms);Random random = new Random();int n = random.Next(10000);Console.WriteLine("任务完成");return n;}static void Main(string[] args){NewTaskDelegate task = newTask;IAsyncResult asyncResult = task.BeginInvoke(2000, null, null);//EndInvoke方法将被阻塞2秒int result = task.EndInvoke(asyncResult);Console.WriteLine(result);Console.Read();}}2、使用IAsyncResult.IsCompleted属性来判断异步调用是否完成复制代码 代码如下:class Program{private delegate int NewTaskDelegate(int ms);private static int newTask(int ms){Console.WriteLine("任务开始");Thread.Sleep(ms);Random random = new Random();int n = random.Next(10000);Console.WriteLine("任务完成");return n;}static void Main(string[] args){NewTaskDelegate task = newTask;IAsyncResult asyncResult = task.BeginInvoke(2000, null, null);//等待异步执行完成while (!asyncResult.IsCompleted){Console.Write("*");Thread.Sleep(100);}// 由于异步调用已经完成,因此, EndInvoke会立刻返回结果int result = task.EndInvoke(asyncResult);Console.WriteLine(result);Console.Read();}}3、使用WaitOne方法等待异步方法执行完成WaitOne的第一个参数表示要等待的毫秒数,在指定时间之内,WaitOne方法将一直等待,直到异步调用完成,并发出通知,WaitOne方法才返回true。当等待指定时间之后,异步调用仍未完成,WaitOne方法返回false,如果指定时间为0,表示不等待,如果为-1,表示永远等待,直到异步调用完成。复制代码 代码如下:class Program{private delegate int NewTaskDelegate(int ms);private static int newTask(int ms){Console.WriteLine("任务开始");Thread.Sleep(ms);Random random = new Random();int n = random.Next(10000);Console.WriteLine("任务完成");return n;}static void Main(string[] args){NewTaskDelegate task = newTask;IAsyncResult asyncResult = task.BeginInvoke(2000, null, null);//等待异步执行完成while (!asyncResult.AsyncWaitHandle.WaitOne(100, false)){Console.Write("*");}int result = task.EndInvoke(asyncResult);Console.WriteLine(result);Console.Read();}}4、使用回调方式返回结果要注意的是“my.BeginInvoke(3,300, MethodCompleted, my)”,BeginInvoke方法的参数传递方式:前面一部分(3,300)是其委托本身的参数。倒数第二个参数(MethodCompleted)是回调方法委托类型,他是回调方法的委托,此委托没有返回值,有一个IAsyncResult类型的参数,当method方法执行完后,系统会自动调用MethodCompleted方法。最后一个参数(my)需要向MethodCompleted方法中传递一些值,一般可以传递被调用方法的委托,这个值可以使用IAsyncResult.AsyncState属性获得。复制代码 代码如下:class Program{private delegate int MyMethod(int second, int millisecond);//线程执行方法private static int method(int second, int millisecond){Console.WriteLine("线程休眠" + (second * 1000 + millisecond) + "毫秒");Thread.Sleep(second * 1000 + millisecond);Random random = new Random();return random.Next(10000);}//回调方法private static void MethodCompleted(IAsyncResult asyncResult){if (asyncResult == null || asyncResult.AsyncState == null){Console.WriteLine("回调失败!!!");return;}int result = (asyncResult.AsyncState as MyMethod).EndInvoke(asyncResult);Console.WriteLine("任务完成,结果:" + result);}static void Main(string[] args){MyMethod my = method;IAsyncResult asyncResult = my.BeginInvoke(3,300, MethodCompleted, my);Console.WriteLine("任务开始");Console.Read();}}5、其他组件的BeginXXX和EndXXX方法在其他的.net组件中也有类似BeginInvoke和EndInvoke的方法,如System.Net.HttpWebRequest类的BeginGetResponse和EndGetResponse方法。其使用方法类似于委托类型的BeginInvoke和EndInvoke方法,例如:复制代码 代码如下:class Program{//回调函数private static void requestCompleted(IAsyncResult asyncResult){if (asyncResult == null || asyncResult.AsyncState==null){Console.WriteLine("回调失败");return;}HttpWebRequest hwr = asyncResult.AsyncState as HttpWebRequest;HttpWebResponse response = (HttpWebResponse)hwr.EndGetResponse(asyncResult);StreamReader sr = new StreamReader(response.GetResponseStream());string str = sr.ReadToEnd();Console.WriteLine("返回流长度:"+str.Length);}static void Main(string[] args){HttpWebRequest request =(HttpWebRequest)WebRequest.Create("http://www.baidu.com");//异步请求IAsyncResult asyncResult = request.BeginGetResponse(requestCompleted, request);Console.WriteLine("任务开始");Console.Read();}}

C# winform动态创建多线程

1 private void Form1_Load(object sender, EventArgs e) 2 { 3 Thread newthread = new Thread(new ThreadStart(BackgroundProcess)); 4 newthread.Start(); 5 6 } 7 8 /// <summary> 9 /// 定义一个代理 10 /// </summary> 11 private delegate void CrossThreadOperationControl();12 13 private void BackgroundProcess()14 {15 // 将代理实例化为一个匿名代理 16 CrossThreadOperationControl CrossDelete = delegate()17 {18 int i = 1;19 while (i < 5)20 {21 // 向列表框增加一个项目 22 listBox1.Items.Add("Item " + i.ToString());23 i++;24 }25 label1.Text = "我在新线程里访问这个lable!";26 listBox1.Items.Add(label1.Text);27 };28 listBox1.Invoke(CrossDelete);29 }收集一下,在C# winform编程中多线程操作控件时,可以有下面种方法:1. 又看到一种方法(2014.1.6): 1. 刚看到一种方法(2014.1.5):1 private void btnTest_Click(object sender, EventArgs e) 2 { 3 if (this.txtIP.Text.Trim() != "" && this.txtPort.Text.Trim() != "") 4 { 5 string proxy = this.txtIP.Text.Trim() + ":" + this.txtPort.Text.Trim(); 6 string result = string.Empty; 7 this.btnTest.Enabled = false; 8 new Thread(delegate 9 {10 Stopwatch stopwatch = new Stopwatch();11 stopwatch.Start();12 HttpClient httpClient = new HttpClient();13 httpClient.Proxy = new WebProxy(proxy);14 httpClient.TimeOut = 2000;15 object result;16 try17 {18 string a = httpClient.Get("http://www.baidu.com", "", "", "", "", "get");19 if (a != "")20 {21 result = "响应成功!";22 }23 else24 {25 result = "响应失败!";26 }27 }28 catch29 {30 }31 stopwatch.Stop();32 result = result;33 result = string.Concat(new object[]34 {35 result,36 ",响应花费:",37 stopwatch.ElapsedMilliseconds,38 "ms"39 });40 this.BeginInvoke(delegate41 {42 this.lbResult.Text = result;43 this.btnTest.Enabled = true;44 });45 })46 {47 IsBackground = true48 }.Start();49 }50 else51 {52 this.lbResult.Text = "请输入完整再提交!";53 }54 }1. 直接使用表达式和Action()1 private void btnInitEnv_Click(object sender, EventArgs e) 2 { 3 //初始化环境时回显出来的文字不让看 4 try 5 { 6 this.textBoxOutPut.Clear(); 7 this.btnInitEnv.Enabled = false; 8 this.labelStateInfo.Text = ""; 9 this.labelStateInfo.ForeColor = Color.Red;10 11 if (!WriteToSerialPort("diags"))12 {13 this.btnInitEnv.Enabled = true;14 return;15 }16 17 Thread thread = new Thread(new ThreadStart(() =>18 {19 int i = 0;20 bool flagFind = false;21 StringBuilder sb = new StringBuilder();22 23 while (true)24 {25 Thread.Sleep(300);26 this.Invoke(new Action(() =>27 {28 sb.Append(this.textBoxOutPut.Text);29 this.textBoxOutPut.Clear();30 if (sb.ToString().Contains("Entering recovery mode, starting command prompt"))31 {32 this.textBoxOutPut.AppendText(string.Format(PubilcConstVar.TerimalStrFormat,33 DateTime.Now.ToString(PubilcConstVar.TimeFormat),34 "Entering recovery mode, starting command prompt, Stop. "));35 this.labelStateInfo.ForeColor = Color.Red;36 this.labelStateInfo.Text = "初始化失败,请手动输入命令初始化";37 flagFind = true;38 this.btnInitEnv.Enabled = true;39 }40 else if (sb.ToString().Contains(":-)"))41 {42 this.textBoxOutPut.AppendText(string.Format(PubilcConstVar.TerimalStrFormat,43 DateTime.Now.ToString(PubilcConstVar.TimeFormat),44 "进入操作模式成功 "));45 this.labelStateInfo.ForeColor = Color.Blue;46 this.labelStateInfo.Text = "初始化成功";47 flagFind = true;48 49 //将业务按钮使能50 EnableBussinessButtons();51 }52 }));53 54 if (flagFind || ++i > 20) //找开标志或10秒超时中断55 {56 break;57 }58 }59 60 if (!flagFind)61 {62 this.Invoke(new Action(() =>63 {64 this.textBoxOutPut.Clear();65 this.labelStateInfo.ForeColor = Color.Red;66 this.labelStateInfo.Text = "初始化失败,超时";67 this.btnInitEnv.Enabled = true;68 69 DisableBussinessButtons();70 }));71 }72 }));73 74 thread.IsBackground = true;75 thread.Start();76 }77 catch (Exception ex)78 {79 this.log.Write(ex.ToString());80 }81 }2. 使用线程函数加action()1 private void btnInitEnv_Click(object sender, EventArgs e) 2 { 3 //初始化环境时回显出来的文字不让看 4 try 5 { 6 this.textBoxOutPut.Clear(); 7 this.btnInitEnv.Enabled = false; 8 this.labelStateInfo.Text = ""; 9 this.labelStateInfo.ForeColor = Color.Red;10 11 if (!WriteToSerialPort("diags"))12 {13 this.btnInitEnv.Enabled = true;14 return;15 }16 17 Thread thread = new Thread(new ThreadStart(MonitorOutPutThread));18 19 thread.IsBackground = true;20 thread.Start();21 }22 catch (Exception ex)23 {24 this.log.Write(ex.ToString());25 }26 }线程函数:1 private void MonitorOutPutThread() 2 { 3 int i = 0; 4 bool flagFind = false; 5 StringBuilder sb = new StringBuilder(); 6 7 while (true) 8 { 9 Thread.Sleep(300);10 this.Invoke(new Action(() =>11 {12 sb.Append(this.textBoxOutPut.Text);13 this.textBoxOutPut.Clear();14 if (sb.ToString().Contains("Entering recovery mode, starting command prompt"))15 {16 this.textBoxOutPut.AppendText(string.Format(PubilcConstVar.TerimalStrFormat,17 DateTime.Now.ToString(PubilcConstVar.TimeFormat),18 "Entering recovery mode, starting command prompt, Stop. "));19 this.labelStateInfo.ForeColor = Color.Red;20 this.labelStateInfo.Text = "初始化失败,请手动输入命令初始化";21 flagFind = true;22 this.btnInitEnv.Enabled = true;23 }24 else if (sb.ToString().Contains(":-)"))25 {26 this.textBoxOutPut.AppendText(string.Format(PubilcConstVar.TerimalStrFormat,27 DateTime.Now.ToString(PubilcConstVar.TimeFormat),28 "进入操作模式成功 "));29 this.labelStateInfo.ForeColor = Color.Blue;30 this.labelStateInfo.Text = "初始化成功";31 flagFind = true;32 33 //将业务按钮使能34 EnableBussinessButtons();35 }36 }));37 38 if (flagFind || ++i > 20) //找开标志或10秒超时中断39 {40 break;41 }42 }43 44 if (!flagFind)45 {46 this.Invoke(new Action(() =>47 {48 this.textBoxOutPut.Clear();49 this.labelStateInfo.ForeColor = Color.Red;50 this.labelStateInfo.Text = "初始化失败,超时";51 this.btnInitEnv.Enabled = true;52 53 DisableBussinessButtons();54 }));55 }56 }

在多线程中使用ArrayList为啥出现java.lang.IndexOutOfBoundsException:错误?

只是因为 超出范围了再看看报错的行,然后解决问题~~~~~~~~~集合中的数量一直是在变化的,却使用一个固定的值去移除

java问题 有一个list有1W条数据, 现在我想用多线程不重复的读取list中的数据,要怎么写?

@Slf4jpublic class FixedThreadPool {/** 请求总数**/private static int clientTotal = 100;public static AtomicInteger atomicInteger = new AtomicInteger(0);public static void main(String[] args) throws Exception {ExecutorService executorService = Executors.newFixedThreadPool(10);final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);for (int i = 0; i < clientTotal; i++) { //这里clientTotal你换成你的list的sizeatomicInteger.incrementAndGet();while (atomicInteger.get() > 4){Thread.sleep(10);}executorService.execute(() -> {consoleLog();countDownLatch.countDown();atomicInteger.decrementAndGet();});}countDownLatch.await();executorService.shutdown();log.info("全部执行完毕");}private static void consoleLog(){try {log.info("hello");Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}}}

java 多线程为什么顺序执行

5个人去上厕所,一个个接着进去,每个人都要蹲一分钟才能拉出来,那你说谁会先拉出来?

调用test方法 只需要3毫秒 而是用现成去执行 有时候 要需要 5毫秒,用多线程去执行 不是应该更快吗?

多线程,并不能使一个方法执行得更快,只是可以“并发”让多个任务同步干活,是整体上快了。

java如何在多线程执行完成后再执行某个方法

java.util.concurrent.CountDownLatch 这个类可以实现你所要的功能例如:CountDownLatch latch = new CountDownLatch(5) //声明计数器为5个Thread t = new Thread() {public void run() {try {//TODO 你的应用} catch (Exception e) {//TODO 异常处理}finally {latch.countDown(); //这句是关键System.out.println("ok"); //5个线程都跑完后输出}}};t.start();然后让以上操作循环五次(就是说同时开5个线程),那么这个"ok"就会在等到这5个线程都ok后才会被输出一次。

java多线程模拟多用户同时查询数据库,计算查询时间。为什么线程跑完后,执行不到t2这部来,无异常显示。

t2这部分不会被运行了countDownLatch 根本就没有执行过countDown的调用你可以首先把countDown变成类的静态成员变量,或者把countDown作为参数带入到类Calc 中,在run方法结束的时候执行countDownLatch.countDown();如果不执行countDownLatch.countDown();操作,计数器不会产生变化,线程跑完了以后程序就停在countDownLatch.await(); 傻等着了........

java如何在多线程执行完后才执行其他任务

设置一个计数器,每个线程执行完后计数器加一然后查看计数器是否已满(任务都完成),没有的话就阻塞,是的话就唤醒其他所有线程,大家一起来执行下一次任务。要注意公用的计数器的线程安全!

Tools:seqkit快速多线程全平台fastq处理工具

seqkit的使用方法 seqkit github mp.weixin.qq.com/s/OJsxFR33ej0ACozNbF_dNA 参数如下: amplicon 通过引物检索扩增子(或其周围的特定区域) bam 检查和在线绘制BAM记录文件的直方图 common 通过id/名称/序列查找多个文件的公共序列 concat 连接多个文件中具有相同ID的序列 convert 转换FASTQ质量编码格式:支持格式包括:桑格,Solexa和Illumina duplicate 重复序列N次 faidx 创建FASTA索引文件并提取子序列 fish 使用局部比对在较大的序列中寻找短序列 fq2fa 转换FASTQ到FASTA fx2tab 将FASTA/Q转换为表格格式(包含长度/GC含量/GC偏好) genautocomplete 生成shell自动完成脚本 grep 通过ID/name/sequence/sequence motif搜索序列,允许错配 head 打印第一条序列 help 打印帮助信息 locate 定位序列,或者motifs,允许错配 mutate 编辑序列(点突变、插入、删除) pair 匹配双端序列文件 range 打印一个范围内的序列 rename 重命名重复序列ID replace 使用正则表达式修改名称或者序列 restart 重置环状基因组的起始位置 rmdup 通过id/名称/序列删除重复的序列 sample 按数量或比例对序列进行抽样 sana 清理损坏的单行fastq文件 scat real time recursive concatenation and streaming of fastx files seq 转换序列(反向,补充,提取ID…) shuffle 随机序列 sliding 序列滑窗提取,支持环形基因组 sort 按id/名称/序列/长度排序序列 split 按id/seq区域/大小/部件将序列拆分为文件(主要用于FASTA) split2 按序列数量/文件数将序列拆分为多个文件(FASTA, PE/SE FASTQ) stats FASTA/Q文件的简单统计 subseq 通过region/gtf/bed得到子序列,包括侧翼序列 tab2fx 转换表格格式为FASTA/Q格式 translate 翻译DNA/RNA到蛋白质序列(支持歧义碱基) version 打印版本信息并检查是否更新 watch 序列特征的监测和在线直方图 seqkit rename --help seqkit seq test.fa -w 0 把多行的转为一行 seqkit seq demo.fa -w 100 把一行的转为多行,每行100个字符 seqkit seq -n test.fa 获取所有序列的名称 seqkit translate -T 1 demo.fa -T参数指定使用的转换模式,1是一般模式。 seqkit seq -i 2.fa >3.fa 提取后,header只保留 XP_012434104.1 seqkit seq -i --id-regexp "([A-Za-z0-9.]{1,30})" -w 0 CAZyDB.07312020.fa >CAZyDB.07312020.fasta 主要是使用 --id-regexp 这个参数,匹配的时候不需要匹配 ^> ,程序会自动匹配ID所在的行,中间的正则,必须用双引号包括一对小括号。小括号内是匹配要保留ID的字符 seqkit sort -N Genome.fa -o test.fa seqkit replace --ignore-case --pattern .+ -r "Chr{nr}" --nr-width 2 test.fa -o genome.new.fa rename.txt格式如下:两列之间是tab分隔符,第一列是旧的ID,第2列是新的ID genome.fa的头部格式是只有ID seqkit faidx genome.fa --infile-list genome.order -o genome.order.fa genome.order是一列文件,是你要排序序列ID的顺序,输出的genome.order.fa是排序后的顺序 seqkit seq --dna2rna Chr_genome_final.fa seqkit seq --rna2dna Chr_final.fa seqkit seq --lower-case test.fa seqkit seq --upper-case test.fa seqkit seq -t DNA --complement test.fa seqkit seq -t RNA --complement test.RNA.fa seqkit seq --reverse test.cds.fa 反向序列 seqkit seq -t DNA --complement --reverse test.cds.fa 反向互补序列 seqkit sample -n 10000 -s 10 test_1.fq -o sample.fq 随机提取10000条序列 seqkit sample -p 0.1 -s 10 test_1.fq -o sample.fq 随机提取总序列的10%的序列

Linux/c++ 多线程写文件时怎么正确使用flockfile/funlockfile

必须要控制! 目录相当于临界资源,必须要在线程实现过程中进行线程同步控制,否则有多个线程并发处理同一个文件的风险,导致一个线程把文件删除后,另外一个线程还在进行读取,导致读取和输出报错。

fwrite fread多线程操作

可以使用文件锁定,对文件的读写进行锁定,通过系统调用fcntl( )实现,它的定义如下:int fcntl(int fildes, int command, struct flock *flock_structure);其中: fildes是文件描述符; command有三个:F_GETLK、F_SETLK、F_SETLKW flock结构体包含以下成员: short l_type short l_whence off_t l_start off_t l_len pid_t l_pid注意:对文件区域加锁之后,必须使用底层的read、write调用来访问文件中的数据,因为fwrite、fread对数据的读写会进行缓存,可能会引起数据的问题。=============================================具体用法搜一搜吧,希望有所帮助。

spring scheduled 是单线程还是多线程

首先要配置我们的spring.xml xmlns 多加下面的内容、 然后xsi:schemaLocation多加下面的内容、 最后是我们的task任务扫描注解 [html] view plaincopy 我的配置扫描位置是: [html] view plaincopy 扫描的是com.test这样的包下的内容、 下面需要

rmi是多线程处理还是单线程

我猜想这是服务器自己决定的,比如它有负载均衡和流量限制能力。像一般 HTTP 的服务器,它都是使用线程池,是多线程,但有池也就有了并发上限。你可以在 debug 模式中运行一个 RMI java 程序,然后看是不是有一堆的 connect worker 之类的名字的线程。当请求进来的 TCP 监听器会查看是否有闲置的 worker 线程,如果有就交给它处理,如果没有而且未达到池程池中线程的数量上限就创建一个 worker 线程放入池中,然后交给它去处理,处理完请求之后这个worker 线程会释放回线程池,达到上限的话就等直到有闲置的释放出来或者报告超时。因为 RMI 访问是个同步的调用,不可能先压入堆栈等待处理,只要有能力处理服务器就应该立即处理,如果没能力那就连第一步取数据的过程都不要处理,直接阻塞客户端的连接直到有 worker 线程闲置时。我想http 的线程池类似RMI的吧。都是远程客户端访问。像 IBM websphere, Sybase Jaguar 之类的服务器都是有 CORBA/ORB 服务器的,都是使用线程池,原理类似于 RMI。

vb.net 多线程卡死界面,新手求前辈们帮助,感谢

“卡死”是一个非常主观的描述,如果你要让主线程杀掉卡死的线程,那么你必须给“卡死”做出准确的定义。什么是卡死?30秒没有响应就是卡死?那么“没有响应”的定义又是什么?你给出这些条件以后,杀掉一个线程就不难。Abort方法,Dispose方法,都可以。

python多线程对多核的利用

GIL 与 Python 线程的纠葛GIL 是什么东西?它对我们的 python 程序会产生什么样的影响?我们先来看一个问题。运行下面这段 python 程序,CPU 占用率是多少?# 请勿在工作中模仿,危险:)def dead_loop():while True:passdead_loop()答案是什么呢,占用 100% CPU?那是单核!还得是没有超线程的古董 CPU。在我的双核 CPU 上,这个死循环只会吃掉我一个核的工作负荷,也就是只占用 50% CPU。那如何能让它在双核机器上占用 100% 的 CPU 呢?答案很容易想到,用两个线程就行了,线程不正是并发分享 CPU 运算资源的吗。可惜答案虽然对了,但做起来可没那么简单。下面的程序在主线程之外又起了一个死循环的线程import threadingdef dead_loop():while True:pass# 新起一个死循环线程t = threading.Thread(target=dead_loop)t.start()# 主线程也进入死循环dead_loop()t.join()按道理它应该能做到占用两个核的 CPU 资源,可是实际运行情况却是没有什么改变,还是只占了 50% CPU 不到。这又是为什么呢?难道 python 线程不是操作系统的原生线程?打开 system monitor 一探究竟,这个占了 50% 的 python 进程确实是有两个线程在跑。那这两个死循环的线程为何不能占满双核 CPU 资源呢?其实幕后的黑手就是 GIL。GIL 的迷思:痛并快乐着GIL 的全称为 Global Interpreter Lock ,意即全局解释器锁。在 Python 语言的主流实现 CPython 中,GIL 是一个货真价实的全局线程锁,在解释器解释执行任何 Python 代码时,都需要先获得这把锁才行,在遇到 I/O 操作时会释放这把锁。如果是纯计算的程序,没有 I/O 操作,解释器会每隔 100 次操作就释放这把锁,让别的线程有机会执行(这个次数可以通过sys.setcheckinterval 来调整)。所以虽然 CPython 的线程库直接封装操作系统的原生线程,但 CPython 进程做为一个整体,同一时间只会有一个获得了 GIL 的线程在跑,其它的线程都处于等待状态等着 GIL 的释放。这也就解释了我们上面的实验结果:虽然有两个死循环的线程,而且有两个物理 CPU 内核,但因为 GIL 的限制,两个线程只是做着分时切换,总的 CPU 占用率还略低于 50%。看起来 python 很不给力啊。GIL 直接导致 CPython 不能利用物理多核的性能加速运算。那为什么会有这样的设计呢?我猜想应该还是历史遗留问题。多核 CPU 在 1990 年代还属于类科幻,Guido van Rossum 在创造 python 的时候,也想不到他的语言有一天会被用到很可能 1000+ 个核的 CPU 上面,一个全局锁搞定多线程安全在那个时代应该是最简单经济的设计了。简单而又能满足需求,那就是合适的设计(对设计来说,应该只有合适与否,而没有好与不好)。怪只怪硬件的发展实在太快了,摩尔定律给软件业的红利这么快就要到头了。短短 20 年不到,代码工人就不能指望仅仅靠升级 CPU 就能让老软件跑的更快了。在多核时代,编程的免费午餐没有了。如果程序不能用并发挤干每个核的运算性能,那就意谓着会被淘汰。对软件如此,对语言也是一样。那 Python 的对策呢?Python 的应对很简单,以不变应万变。在最新的 python 3 中依然有 GIL。之所以不去掉,原因嘛,不外以下几点:欲练神功,挥刀自宫:CPython 的 GIL 本意是用来保护所有全局的解释器和环境状态变量的。如果去掉 GIL,就需要多个更细粒度的锁对解释器的众多全局状态进行保护。或者采用 Lock-Free 算法。无论哪一种,要做到多线程安全都会比单使用 GIL 一个锁要难的多。而且改动的对象还是有 20 年历史的 CPython 代码树,更不论有这么多第三方的扩展也在依赖 GIL。对 Python 社区来说,这不异于挥刀自宫,重新来过。就算自宫,也未必成功:有位牛人曾经做了一个验证用的 CPython,将 GIL 去掉,加入了更多的细粒度锁。但是经过实际的测试,对单线程程序来说,这个版本有很大的性能下降,只有在利用的物理 CPU 超过一定数目后,才会比 GIL 版本的性能好。这也难怪。单线程本来就不需要什么锁。单就锁管理本身来说,锁 GIL 这个粗粒度的锁肯定比管理众多细粒度的锁要快的多。而现在绝大部分的 python 程序都是单线程的。再者,从需求来说,使用 python 绝不是因为看中它的运算性能。就算能利用多核,它的性能也不可能和 C/C++ 比肩。费了大力气把 GIL 拿掉,反而让大部分的程序都变慢了,这不是南辕北辙吗。难道 Python 这么优秀的语言真的仅仅因为改动困难和意义不大就放弃多核时代了吗?其实,不做改动最最重要的原因还在于:不用自宫,也一样能成功!其它神功那除了切掉 GIL 外,果然还有方法让 Python 在多核时代活的滋润?让我们回到本文最初的那个问题:如何能让这个死循环的 Python 脚本在双核机器上占用 100% 的 CPU?其实最简单的答案应该是:运行两个 python 死循环的程序!也就是说,用两个分别占满一个 CPU 内核的 python 进程来做到。确实,多进程也是利用多个 CPU 的好方法。只是进程间内存地址空间独立,互相协同通信要比多线程麻烦很多。有感于此,Python 在 2.6 里新引入了 multiprocessing这个多进程标准库,让多进程的 python 程序编写简化到类似多线程的程度,大大减轻了 GIL 带来的不能利用多核的尴尬。这还只是一个方法,如果不想用多进程这样重量级的解决方案,还有个更彻底的方案,放弃 Python,改用 C/C++。当然,你也不用做的这么绝,只需要把关键部分用 C/C++ 写成 Python 扩展,其它部分还是用 Python 来写,让 Python 的归 Python,C 的归 C。一般计算密集性的程序都会用 C 代码编写并通过扩展的方式集成到 Python 脚本里(如 NumPy 模块)。在扩展里就完全可以用 C 创建原生线程,而且不用锁 GIL,充分利用 CPU 的计算资源了。不过,写 Python 扩展总是让人觉得很复杂。好在 Python 还有另一种与 C 模块进行互通的机制 : ctypes利用 ctypes 绕过 GILctypes 与 Python 扩展不同,它可以让 Python 直接调用任意的 C 动态库的导出函数。你所要做的只是用 ctypes 写些 python 代码即可。最酷的是,ctypes 会在调用 C 函数前释放 GIL。所以,我们可以通过 ctypes 和 C 动态库来让 python 充分利用物理内核的计算能力。让我们来实际验证一下,这次我们用 C 写一个死循环函数extern"C"{void DeadLoop(){while (true);}}用上面的 C 代码编译生成动态库 libdead_loop.so (Windows 上是 dead_loop.dll),接着就要利用 ctypes 来在 python 里 load 这个动态库,分别在主线程和新建线程里调用其中的 DeadLoopfrom ctypes import *from threading import Threadlib = cdll.LoadLibrary("libdead_loop.so")t = Thread(target=lib.DeadLoop)t.start()lib.DeadLoop()这回再看看 system monitor,Python 解释器进程有两个线程在跑,而且双核 CPU 全被占满了,ctypes 确实很给力!需要提醒的是,GIL 是被 ctypes 在调用 C 函数前释放的。但是 Python 解释器还是会在执行任意一段 Python 代码时锁 GIL 的。如果你使用 Python 的代码做为 C 函数的 callback,那么只要 Python 的 callback 方法被执行时,GIL 还是会跳出来的。比如下面的例子:extern"C"{typedef void Callback();void Call(Callback* callback){callback();}}from ctypes import *from threading import Threaddef dead_loop():while True:passlib = cdll.LoadLibrary("libcall.so")Callback = CFUNCTYPE(None)callback = Callback(dead_loop)t = Thread(target=lib.Call, args=(callback,))t.start()lib.Call(callback)注意这里与上个例子的不同之处,这次的死循环是发生在 Python 代码里 (DeadLoop 函数) 而 C 代码只是负责去调用这个 callback 而已。运行这个例子,你会发现 CPU 占用率还是只有 50% 不到。GIL 又起作用了。其实,从上面的例子,我们还能看出 ctypes 的一个应用,那就是用 Python 写自动化测试用例,通过 ctypes 直接调用 C 模块的接口来对这个模块进行黑盒测试,哪怕是有关该模块 C 接口的多线程安全方面的测试,ctypes 也一样能做到。结语虽然 CPython 的线程库封装了操作系统的原生线程,但却因为 GIL 的存在导致多线程不能利用多个 CPU 内核的计算能力。好在现在 Python 有了易经筋(multiprocessing), 吸星大法(C 语言扩展机制)和独孤九剑(ctypes),足以应付多核时代的挑战,GIL 切还是不切已经不重要了,不是吗。

C# 关于多线程和CPU的问题

线程中间有个sleep方法。 程序中有死循环而且中间没用sleep所有导致的。循环一次一定要sleep一下。要不他一直占住CPU不释放,导致程序死锁。在线程里面加上 :System.Threading.Thread.Sleep(10000);就能解决这个问题了。

FX8350与i7 3770 多线程性能问题

楼主这个分数 很明显要给我 咯 呵呵。我只是稍微提示一下。3770可是 4核心 8线程哦。I7可是8线程摆在那里哦。虽然FX是8核心,可是 Autoform多线程优化确实强大,超线程工作 强悍不得了。I7 可是超线程哦!!

c#中Timer是单线程还是多线程?

C#库中的Timer好像有三个:Fomr中的Timer是会占用窗体线程的,通俗的说,可能会卡住界面System.Threading中的Timer是会单独开线程的。另外一个Timer我实在记不起来了,一般都推荐用System.Threading中的Timer

c#中Timer是单线程还是多线程?

多线程..用时候还是要考虑下的..比如timer处理的程序执行完毕需要5秒,但timer间隔只设置了5秒以下的话.很多程序就会有冲突了.有必要的话在timer事件开始时先把timer控件停止,再timer事件结束前再开下timertimer.enable=false;timer.enable=true;

C语言中的MPI编程和多线程有什么区别,MPI编程中针对的是一台电脑多核还是多台电脑?谢谢!

MPI(MPI是一个标准,有不同的具体实现,比如MPICH等)是多主机联网协作进行并行计算的工具,当然也可以用于单主机上多核/多CPU的并行计算,不过效率低。它能协调多台主机间的并行计算,因此并行规模上的可伸缩性很强,能在从个人电脑到世界TOP10的超级计算机上使用。缺点是使用进程间通信的方式协调并行计算,这导致并行效率较低、内存开销大、不直观、编程麻烦。OpenMP是针对单主机上多核/多CPU并行计算而设计的工具,换句话说,OpenMP更适合单台计算机共享内存结构上的并行计算。由于使用线程间共享内存的方式协调并行计算,它在多核/多CPU结构上的效率很高、内存开销小、编程语句简洁直观,因此编程容易、编译器实现也容易(现在最新版的C、C++、Fortran编译器基本上都内置OpenMP支持)。不过OpenMP最大的缺点是只能在单台主机上工作,不能用于多台主机间的并行计算!如果要多主机联网使用OpenMP(比如在超级计算机上),那必须有额外的工具帮助,比如MPI+OpenMP混合编程。或者是将多主机虚拟成一个共享内存环境(Intel有这样的平台),但这么做效率还不如混合编程,唯一的好处是编程人员可以不必额外学习MPI编程。

mysql 类似oracle parallel的多线程查询

没.. 70w数据建议建议分表了

Java多线程编程中lock.lock()是什么意思,在线等

就是jdk5开始的锁机制啊,Lock lock = ...;lock.lock()加锁了啊

单例模式可用于多线程应用程序吗

可以说单例模式是所有设计模式中最简单的一种。单例模式就是说系统中对于某类的只能有一个对象,不可能出来第二个。单例模式也是23中设计模式中在面试时少数几个会要求写代码的模式之一。主要考察的是多线程下面单例模式的线程安全性问题。1.多线程安全单例模式实例一(不使用同步锁)1 public class Singleton {2 private static Singleton sin=new Singleton(); ///直接初始化一个实例对象3 private Singleton(){ ///private类型的构造函数,保证其他类对象不能直接new一个该对象的实例4 }5 public static Singleton getSin(){ ///该类唯一的一个public方法 6 return sin;7 }8 }上述代码中的一个缺点是该类加载的时候就会直接new 一个静态对象出来,当系统中这样的类较多时,会使得启动速度变慢 。现在流行的设计都是讲“延迟加载”,我们可以在第一次使用的时候才初始化第一个该类对象。所以这种适合在小系统。 2.多线程安全单例模式实例二(使用同步方法)1 public class Singleton {2 private static Singleton instance;3 private Singleton (){45 }6 public static synchronized Singleton getInstance(){ //对获取实例的方法进行同步7 if (instance == null)8 instance = new Singleton();9 return instance;10 }11 } 上述代码中的一次锁住了一个方法, 这个粒度有点大 ,改进就是只锁住其中的new语句就OK。就是所谓的“双重锁”机制。3.多线程安全单例模式实例三(使用双重同步锁)1 public class Singleton {2 private static Singleton instance;3 private Singleton (){4 }5 public static Singleton getInstance(){ //对获取实例的方法进行同步6 if (instance == null){7 synchronized(Singleton.class){8 if (instance == null)9 instance = new Singleton(); 10 }11 }12 return instance;13 }14 15 }

单例模式多线程问题

单例模式不自带线程安全的功能。你上面的getInstance只是在创建的时候能够防止创建出两个实例。printCount不是线程安全的

Java多线程之阻塞I/O如何中断

阻塞的I/O线程在关闭线程时并不会被打断,需要关闭资源才能打断。1.执行socketInput.close();阻塞可中断。2.执行System.in.close();阻塞没有中断。复制代码package Thread.Interrupting;import java.io.IOException;import java.io.InputStream;import java.net.ServerSocket;import java.net.Socket;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;public class CloseResource {public static void main(String[] args) throws Exception {//堵塞的I/O线程不会被打断,需要关闭资源才能打断ExecutorService exec = Executors.newCachedThreadPool();ServerSocket server = new ServerSocket(8080);InputStream socketInput = new Socket("localhost", 8080).getInputStream();exec.execute(new IOBlocked(socketInput));exec.execute(new IOBlocked(System.in));TimeUnit.MILLISECONDS.sleep(100);System.out.println("Shutting down all threads");exec.shutdownNow();TimeUnit.SECONDS.sleep(1);System.out.println("Closing " + socketInput.getClass().getName());socketInput.close();TimeUnit.SECONDS.sleep(1);System.out.println("Close " + System.in.getClass().getName());System.in.close();}}复制代码被阻塞的nio通道在关闭线程后会自动响应中断阻塞,不需要关闭底层资源。复制代码package Thread.Interrupting;import java.io.IOException;import java.net.InetSocketAddress;import java.net.ServerSocket;import java.nio.ByteBuffer;import java.nio.channels.AsynchronousCloseException;import java.nio.channels.ClosedByInterruptException;import java.nio.channels.SocketChannel;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;import java.util.concurrent.TimeUnit;class NIOBlocked implements Runnable {private final SocketChannel sc;public NIOBlocked(SocketChannel sc) {this.sc = sc;}@Overridepublic void run() {try {System.out.println("Waiting for read() in " + this);sc.read(ByteBuffer.allocate(1));} catch (ClosedByInterruptException e) {System.out.println("ClosedByInterruptException");} catch (AsynchronousCloseException e) {System.out.println("AsynchronousCloseException");} catch (IOException e) {throw new RuntimeException(e);}System.out.println("Exiting NIOBlocked.run() " + this);}}public class NIOInterruption {public static void main(String[] args) throws Exception {//被阻塞的nio通道会自动地响应中断ExecutorService exec = Executors.newCachedThreadPool();ServerSocket server = new ServerSocket(8080);InetSocketAddress isa = new InetSocketAddress("localhost", 8080);SocketChannel sc1 = SocketChannel.open(isa);SocketChannel sc2 = SocketChannel.open(isa);Future<?> f = exec.submit(new NIOBlocked(sc1));exec.execute(new NIOBlocked(sc2));exec.shutdown();TimeUnit.SECONDS.sleep(1);f.cancel(true);TimeUnit.SECONDS.sleep(1);sc2.close();}}

java多线程同步的问题

a>bc c>d

java多线程中,同步synchronized(){}括号中应该些什么?

括号里的东西就是你要操作的内容呀,一个操作的逻辑,一串代码当然了,这个东西对所有试图访问它的人来说是共有的,同时只允许一个人去做举个很简单的例子,有一个打印机,同时好几个人想去用它synchronized{applyPrinter(); // 申请使用打印机}当然了,也可以把这个方法声明为synchronized的 synchronized void applyPrinter();也可以用Lock去做

JAVA多线程中的synchronized(obj)到底怎么用?

线程锁,即操作一个对象时,加入A正在操作,那么B只能等待A操作完后才能进行操作,在单例模式和多线程中用的蛮多.

java多线程中synchronized关键字的用法

  由于同一进程内的多个线程共享内存空间 在Java中 就是共享实例 当多个线程试图同时修改某个实例的内容时 就会造成冲突 因此 线程必须实现共享互斥 使多线程同步   最简单的同步是将一个方法标记为synchronized 对同一个实例来说 任一时刻只能有一个synchronized方法在执行 当一个方法正在执行某个synchronized方法时 其他线程如果想要执行这个实例的任意一个synchronized方法 都必须等待当前执行 synchronized方法的线程退出此方法后 才能依次执行   但是 非synchronized方法不受影响 不管当前有没有执行synchronized方法 非synchronized方法都可以被多个线程同时执行   此外 必须注意 只有同一实例的synchronized方法同一时间只能被一个线程执行 不同实例的synchronized方法是可以并发的 例如 class A定义了synchronized方法sync() 则不同实例a sync()和a sync()可以同时由两个线程来执行   多线程同步的实现最终依赖锁机制 我们可以想象某一共享资源是一间屋子 每个人都是一个线程 当A希望进入房间时 他必须获得门锁 一旦A获得门锁 他进去后就立刻将门锁上 于是B C D就不得不在门外等待 直到A释放锁出来后 B C D中的某一人抢到了该锁(具体抢法依赖于 JVM的实现 可以先到先得 也可以随机挑选) 然后进屋又将门锁上 这样 任一时刻最多有一人在屋内(使用共享资源)   Java语言规范内置了对多线程的支持 对于Java程序来说 每一个对象实例都有一把 锁 一旦某个线程获得了该锁 别的线程如果希望获得该锁 只能等待这个线程释放锁之后 获得锁的方法只有一个 就是synchronized关键字 例如   public class SharedResource {   private int count = ;   public int getCount() { return count; }   public synchronized void setCount(int count) { unt = count; }   }   同步方法public synchronized void setCount(int count) { unt = count; } 事实上相当于   public void setCount(int count) {   synchronized(this) { // 在此获得this锁   unt = count;   } // 在此释放this锁   }   红色部分表示需要同步的代码段 该区域为 危险区域 如果两个以上的线程同时执行 会引发冲突 因此 要更改SharedResource的内部状态 必须先获得SharedResource实例的锁   退出synchronized块时 线程拥有的锁自动释放 于是 别的线程又可以获取该锁了   为了提高性能 不一定要锁定this 例如 SharedResource有两个独立变化的变量   public class SharedResouce {   private int a = ;   private int b = ;   public synchronized void setA(int a) { this a = a; }   public synchronized void setB(int b) { this b = b; }   }   若同步整个方法 则setA()的时候无法setB() setB()时无法setA() 为了提高性能 可以使用不同对象的锁   public class SharedResouce {   private int a = ;   private int b = ;   private Object sync_a = new Object()   private Object sync_b = new Object()   public void setA(int a) {   synchronized(sync_a) {   this a = a;   }   }   public synchronized void setB(int b) {   synchronized(sync_b) {   this b = b;   } lishixinzhi/Article/program/Java/gj/201311/27512

多线程:所有线程执行到一个地方才往下执行,怎么实现

主线程抛出一个子线程异步处理一些东西,这时主线程要等待子线程运行完成再完成(其实我是为了统计运行时间的)。这里抛出的子线程可能递归的调用自己,就是再抛一个他的子线程出来,但是到底一共抛多少,事先是不知道的。应用场景:1)多线程扫描文件夹内的文件,遇到文件夹内有子文件夹,要递归调用扫描线程的,等到全部扫描完成后,返回结果,显示;2)多线程快速排序,第一次肯定是单线程的,第一次排序完成后,会分两半,这两半多线程排,递归调用了这个排序线程,这两半很有可能,极大有可能再各分两半,也就是会有4个子线程的子线程再排序。我试过网上的那个 CountDownLatch ,但是他只能实现定义好子线程的数量,但是在以上两种情景下,事先你是不知道会有多少个子线程的!PS:在某种需求中,比如一个大型的任务,常常需要分配好多子任务去执行,只有当所有子任务都执行完成时候,才能执行主任务,这时候,就可以选择CyclicBarrier了。这个貌似也要在开始的时候设定总线程数:CyclicBarrier(int parties)这个和countDownLatch就差不多了呢!你觉得呢 问题补充:niuzai 写道亲,CyclicBarrier可能是你想要的。PS:在某种需求中,比如一个大型的任务,常常需要分配好多子任务去执行,只有当所有子任务都执行完成时候,才能执行主任务,这时候,就可以选择CyclicBarrier了。我再来看看~~试试看! 问题补充:niuzai 写道亲,CyclicBarrier这个东东是可以动态重置个数的,而countDownLatch是一次性的。只不过大多数例子CyclicBarrier初始化了个数罢了,实质上它是可以动态改变的~ 嗯 我试了下,多线程快排,小数据量还好,顺利执行了,但是数多了后,会建N多线程等待,会outofmemory,呵呵!不过证明这个方法是可以的! 问题补充:niuzai 写道亲,那你就结合线程池操作,设置线程数目上限。不要每个任务就产生一个线程咯~ 产生新的线程是很耗内存的,线程太多当然就内存溢出咯~嗯 你说的很对!要结合线程池的!

java中怎样实现多线程执行的结果相加

定义一个成员变量,在线程里加到成员变量里就好了。

java的多线程不异步怎么办

可使用同步组件CountDownLatch、CyclicBarrier等使异程同步。Java异步会导致代码出现诸多不可控因素,这时可可使用同步组件CountDownLatch、CyclicBarrier等进行修复。多线程并发时,多个线程同时请求同一个资源,必然导致此资源的数据不安全,A线程修改了B线程的处理的数据,而B线程又修改了A线程处理的数理。显然这是由于全局资源造成的,有时为了解决此问题,优先考虑使用局部变量,退而求其次使用同步代码块,出于这样的安全考虑就必须牺牲系统处理性能,加在多线程并发时资源挣夺最激烈的地方,这就实现了线程的同步机制。
 1 2  下一页  尾页