线程

创建线程函数,设置静态线程函数

最后都变了- 提交于 2020-03-05 08:24:41
创建线程函数 uintptr_t _beginthreadex( void *security, //线程的安全属性 unsigned stack_size,//线程大小 unsigned ( __stdcall *start_address )( void * ),//线程函数 void *arglist,//线程参数 unsigned initflag,//标识,设置为0,标识立即运行 unsigned *thrdaddr //线程id ); 创建成功,返回一个句柄 如 HANDLE h = (HANDLE)_beginthreadex(0,0,&ThreadAccept,0,0,0); 线程函数ThreadAccept一般设置为全局函数。因为在 unsigned ( __stdcall *start_address )( void * )内是一个普通的函数指针。 但是由于全局函数不方便管理,所以将线程函数作为一个类成员。但是作为类成员后,普通的函数指针无法访问。那我们可以将线程函数设置为静态类成员,即 static unsigned __stdcall ThreadAccept ( void * ); 相当于全局函数,这样在哪个地方都可以访问使用了。 来源: CSDN 作者: weixin_44084204 链接: https://blog.csdn.net/weixin

netty线程模型

a 夏天 提交于 2020-03-05 07:25:05
启动ServerBootstrap时,由main(启动线程)初始化bossGroup和childGroup,启动boss NioEventloop对应的thread,将 NioServerSocketChannel(监听的端口) 注册任务添加到该NioEventloop的taskQueue。线程启动后监听连接(ServerBootstrapAcceptor.channelRead)并runAllTasks。 有连接到来,boss从childGroup选择一个NioEventloop,如果该NioEventloop未绑定线程,则启动线程,将 NioSocketChannel(建立的连接) 注册到child NioEventloop的任务添加到该NioEventloop的taskQueue。线程启动后监听read并runAllTasks。 当有新的连接建立(channel),boss group中执行选择worker group中的NioEventLoop(next)。 boss group 开启worker线程: 默认ThreadPerTaskExecutor,每个NioEventloop创建一个线程。 SingleThreadEventExecutor.execute.startThread。 开启当前NioEventLoop的woker线程,执行NioEventLoop.run。

探索未知种族之osg类生物---呼吸分解之渲染遍历二

狂风中的少年 提交于 2020-03-05 06:49:57
那么今天我们就正式进入osg整个呼吸动作之中最复杂的一个动作,ViewerBase::renderingTraversals(),我们先介绍renderingTraversals的开头的简单的几步操作。 1、这个函数中先遍历了所有的view中的相机节点分别取得他们的位置Translation以及姿态Rotation,并保存到osg内置的log系统中。 2、得到所有的渲染上下文contexts,然后使用 ViewerBase::checkWindowStatus 检查是否存在有效的渲染上下文,没有的话,需要使用 ViewerBase::stopThreading 释放每个camera对应的渲染器以及停止所有的图形线程和相机线程的运行。 3、记录渲染循环开始的时间,最后会相应的进行统计,此次渲染循环进行了多久,方便开发人员调试。 4、通过getViewerFrameStamp()得到记录了仿真循环运行的参考时间,总时间和总帧数的类osg::FrameStamp中的变量_frameStamp。所以你们需要获取这些信息的话,也可以通过读取这个变量的成员函数来实现。当然,使用 Viewer 中的 osg::Stats 变量_stats 也是可以的,缺省情况下,这个变量会忠 实地记录当前帧以及之前的 24 帧的每帧用时,事件遍历用时,更新遍历用时,以及渲染遍 历用时信息

nodejs多线程,真正的非阻塞

妖精的绣舞 提交于 2020-03-05 05:55:09
node从他推出至今,充满赞美和饱受诟病的都是其单线程模型,所有的任务都在一个线程中完成(I/O等例外),优势的地方自然是免去了频繁切换线程的开销,以及减少资源互抢的问题等等,但是当nodejs面对cpu密集型模型的时候就力不从心了。尽管node拥有异步机制,可以把一些耗时算法丢入eventloop等待下个事件循环再做,但是因为其任然是单线程模型,所以终究会造成阻塞。 先解释一下两个名词,Fibers 和 Threads。 Fibers 又称纤程,可以理解为协同程序,类似py和lua都有这样的模型。使用Fibers可以避免对资源的互抢,减少cpu和内存的消耗,但是Fibers并不能够真正的并行执行,同一时刻只有一个Fibers在执行,如果在其中一个Fibers中执行过多的cpu操作或者写了个死循环,则整个主程序将卡死住。node中的异步事件循环模型就有点象这个。 Threads 又称线程,他可以在同一时刻并行的执行,他们共享主进程的内存,在其中某一时刻某一个threads锁死了,是不会影响主线程以及其他线程的执行。但是为了实现这个模型,我们不得不消耗更多的内存和cpu为线程切换的开销,同时也存在可能多个线程对同一内存单元进行读写而造成程序崩溃的问题。 很多让node支持多线程的方法是使用c/c++的addon来实现,在需要进行cpu密集型计算的地方,把js代码改写成c/c++代码

JVM学习【二】---对象的内存布局

两盒软妹~` 提交于 2020-03-05 02:29:15
二、对象(实例)的内存布局 1.对象的创建 虚拟机遇到一个new指令 检查这个指令的参数是否能在常量池中定位到一个类的符号引用 检查这个符号引用代表的类是否已经被加载、解析、初始化过。 如果没有,则执行类加载过程。(如果有,直接为新对象分配内存) 类加载检查通过后,vm为新生对象分配内存。(对象所需要的内存大小,在类加载完成后就能完全确定) 根据不同情况选取,内存分配策略:1)指针碰撞。2)空闲列表。(采取哪种分配方式由内存是否规整决定,内存是否规整由GC策略决定) 指针碰撞:堆中的内存是足够规整的,占用中内存和空闲内存以一个指针为分割,各占内存的一边。此时分配内存,只需要移动指针到对象大小的距离。这种分配方式叫做指针碰撞。 空闲列表:堆中的内存不规整,无法通过一个指针去标识,vm必须维护一个空闲内存列表,在分配时找出一块足够大的内存去分配,并更新列表记录,这种分配方式叫做空闲列表。 在TLAB中分配空间。(TLAB本地线程分配缓存,用于解决并发问题,线程1给A分配内存,刚分配完,指针还没修改或是列表还没更新,线程2又使用了刚刚的指针分配给B了内存,为了保证内存分配的安全,每个线程都预分配了一个独立的内存缓冲区,每个线程分配内存时,都在自己的缓冲区内存里分配,等缓冲区内的内存用完了,再使用同步锁定保证原子性。) 内存分配完成后(指针移位,列表同步),已分配的内存空间都初始化为0

Android 子线程间通信

时光总嘲笑我的痴心妄想 提交于 2020-03-05 01:53:18
1.在android中我们平时处理的都是子线程与主线程间的通信,采用的方法是利用android中的消息循环机制,说白了就是利用Handler 而子线程与子线程的通信也可以用到Handler,也可以通过全局变量来进行通信 2.消息循环机制就不说了,由于主线程在应用启动的时候系统就给它生成了Looper , MessageQueue等消息循环的东西,所以每次子线程 可以直接往主线程发送message。而子线程是不会自动生成Looper的,就要调用Looper.prepare();方法来为该子线程生成Looper, 生成后调用Loopre.loop()来启动消息队列,再在子线程中定义自己的Handler,其他子线程可以调用该Handler来进行,子线程间的通信了。 3.示例代码: 子线程一:    1       new Thread(new Runnable() { 2 3 @Override 4 public void run() { 5 String msg; 6 Looper.prepare(); 7 8 childHandler = new Handler() { 9 @Override 10 public void handleMessage(Message msg) { 11 super.handleMessage(msg); 12 13 System.out

并发数据结构:迷人的原子

为君一笑 提交于 2020-03-05 01:47:21
随着多核CPU成为主流,并行程序设计亦成为研究领域的热门。 要想利用多核/多路CPU带来的强大功能,通常使用多线程来开发应用程序。但是要想拥有良好的硬件利用率,仅仅简单的在多个线程间分割工作是不够的。还必须确保线程大部分时间在工作,而不是在等待工作或等待锁定共享数据结构。 在不止一个线程访问共享数据时,所有线程都必须使用同步。如果线程间不进行协调,则没有任务可以真正并行,更糟糕的是这会给程序带来毁灭性的错误。 现在让我们来看一下在.NET和D语言中的标准同步手段-锁定。.NET下我们使用lock关键字,而D语言则使用 synchronized关键字。它们在Windows下均使用临界区(Critical Section)来实现,而在Linux下则使用互斥锁(Mutex)来实现。不论其如何实现,它们均强制实行互斥,来确保持有锁的线程对共享数据的独占访问权,以及当其他线程持有锁时,可以看到其对共享数据的修改。 简而言之,在基于锁的多线程编程中,任何针对共享数据,且有可能导致竞争条件的操作,我们都得将其改为原子操作(即连续的,不允许被打断的步骤;上面的lock/ synchronized 关键字就是我们实现原子操作的手段)。只要我们的线程持有锁,就不必担心其他线程会进来捣乱。 这听起来似乎很不错,我们只要加锁/解锁就可以为所欲为了。然而正是这种为所欲为的事实带来了问题

托管堆和垃圾回收(GC)

自闭症网瘾萝莉.ら 提交于 2020-03-05 01:20:24
一、基础 首先,为了深入了解垃圾回收(GC),我们要了解一些基础知识: CLR :Common Language Runtime,即公共语言运行时,是一个可由多种面向CLR的编程语言使用的“运行时”,包括内存管理、程序集加载、安全性、异常处理和线程同步等核心功能。 托管进程中的两种内存堆: 托管堆 :CLR维护的用于管理引用类型对象的堆,在进程初始化时,由CLR划出一个地址空间区域作为托管堆。当区域被非垃圾对象填满后,CLR会分配更多的区域,直到整个进程地址空间(受进程的虚拟地址空间限制,32位进程最多分配1.5GB,而64位最多可分配8TB)被填满。 本机堆 :由名为VirtualAlloc的Windows API分配的,用于非托管代码所需的内存。 NextObjPtr :CLR维护的一个指针,指向下一个对象在堆中的分配位置。初始为地址空间区域的基地址。 CLR将对象分为大对象和小对象,两者分配的地址空间区域不同。我们下方的讲解更关注小对象。 大对象 :大于等于85000字节的对象。“85000”并非常数,未来可能会更改。 小对象 :小于85000字节 的对象。 然后明确几个前提: CLR要求所有引用类型对象都从托管堆分配。 C#是运行于CLR之上的。 C# new 一个新对象时,CLR会执行以下操作: 计算类型的字段(包括从基类继承的字段)所需的字节数。

【Android FFMPEG 开发】C++ 回调 Java 方法 模板 ( JavaVM *vm | JNIEnv *env | jobject instance | 引用类型 | 模板代码示例 )

南笙酒味 提交于 2020-03-05 00:05:41
文章目录 I . Native 调用 Java 方法 II . JNIEnv *env 与 jobject instance III . JavaVM *vm IV . 局部引用 与 全局引用 分析 V . Native 调用 Java 方法 ( 主线程 ) VI . Native 调用 Java 方法 ( 子线程 ) VII . Java 层方法 VIII . C++ Java 调用助手类 ( JavaCallHelper.h 头文件 ) IX . C++ Java 调用助手类 ( JavaCallHelper.cpp ) X . Native 入口 C++ 方法 I . Native 调用 Java 方法 1 . 前置知识点 : 参考 【Android NDK 开发】JNI 方法解析 ( C/C++ 调用 Java 方法 | 函数签名 | 调用对象方法 | 调用静态方法 ) 博客内容 , 了解如何在 C++ 中调用 Java 方法 ; 2 . Native 调用 Java 方法 流程如下 : ① 获取函数签名 : 查找字节码文件 , 使用 javap 获取函数签名 ; ② 反射获取 Java 方法 : 通过调用 jmethodID GetMethodID(jclass clazz, const char* name, const char* sig) 方法获取方法 ID ; ③

同步和异步的执行概念和区别

心已入冬 提交于 2020-03-04 23:50:35
转载:iteye.com/blog/avaj-151724 所谓同步,可以理解为在执行完一个函数或方法之后,一直等待系统返回值或消息,这时程序是出于阻塞的,只有接收到返回的值或消息后才往下执行其他的命令。 异步,执行完函数或方法后,不必阻塞性地等待返回值或消息,只需要向系统委托一个异步过程,那么当系统接收到返回值或消息时,系统会自动触发委托的异步过程,从而完成一个完整的流程。 并不是说谁好谁不好,只是同步的机制不适合在正式应用的项目当中(但自己测试还是可以的) 同步,就是实时处理,比如服务器一接收客户端请求,马上响应,这样客户端可以在最短的时间内得到结果,但是如果多个客户端,或者一个客户端发出的请求很频繁,服务器无法同步处理,就会造成涌塞。 异步,就是分时处理,服务器接收到客户端请求后并不是立即处理,而是等待服务器比较空闲的时候加以处理,可以避免涌塞。 同步和异步之分: 同步就是调用一个函数,直接函数执行完了才返回到调用函数 异步就是被调用函数初始化完后马上返回。 同步就是(我死心眼)我等你(给我回答),异步就是(我很忙)我不等你(给我回答) 严格的说,异步还是有两种: 一种是等,但是等的过程和同步不一样,等的时候可以做别的工作,但是程序的主线还是等待 WaitforSingleObject(hEvent,INFINTE,TRUE); 另外一种是CALLBACK方式