首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

CC++:std::thread构造函数死锁问题:WIN32下不可以在DllMain中创建线程

最近在设计一个动态库时,在全局变量中创建了线程,在Windows下动态库加载时导致死锁。根本的原因是Windows要求不可以在动态库的DllMain函数中创建线程,而我的代码结构恰好满足这个条件。...extern "C" __declspec(dllexport) void hello() { } 上面的代码中A类的构造函数中创建了线程,a对象被定义为全局变量,不论是作为exe还是dll执行a都会在程序启动初始化阶段被执行初始化...当在动态库执行时,这个a对象的初始化是在动态库入口点(DllMain entry point),也就是DllMain函数中完成的。...std::thread的构造函数中创建新线程,在新线程开始执行线程过程之前不能返回。...因此,会造成线程互锁:在新线程开始执行线程过程之前,当前线程无法释放加载器锁,但新线程在获取加载器锁之前无法执行线程过程,因为加载器锁由当前线程持有。

87230

从Native到Web(二), NaCl学习笔记: 技术限制&Win32移植过程

一些限制 相对于Win32来说, NaCl相当于另一个平台, 一些操作系统相关的API需要移植....) Pepper API 必须从主线程调用 (对于引擎的多线程架构有所冲击: IO, OpenGL, Input...)...必须同时支持32位和64位 (很多游戏引擎没有考虑64位, 需要解决一些兼容问题) C runtime只支持GLIBC和newlib (一些操作系统相关的API必须改成标准库实现) 渲染使用OpenGL...这些限制都是为了保证安全性(想想ActiveX为什么失败了)和跨平台(Win/Linux/OSX使用同一个版本) 从Win32到NaCl 参考nacl_sdk\vs_addin\examples\hello_nacl_cpp...\hello_nacl_cpp.sln 使用PPAPI平台编译运行(编译成Chrome DLL插件, 可以调用现有的Win32API, 保证了移植过程的平滑) 实现Native Client Framework

82120
您找到你想要的搜索结果了吗?
是的
没有找到

【专业技术第五讲】动态链接库及其用法

使用动态链接库可以更为容易地将更新应用于各个模块,不会影响该程序的其他部分。...您可以使用入口点函数根据 DLL 的需要来初始化数据结构或者销毁数据结构。此外,如果应用程序是多线程的,则可以在入口点函数中使用线程本地存储(TLS) 来分配各个线程专用的内存。...为此,请使用 TLS 为各个线程提供唯一的数据。 如何导出 要导出 DLL 函数,您可以向导出的 DLL 函数中添加函数关键字,也可以创建模块定义文件(.def) 以列出导出的 DLL 函数。...特别调用 关于特定情况下的调用,比如DLL函数中使用到了 Win32 API 或者将 C++ 生成的 DLL 供标准C语言使用,则需要注意以下一些情况: 如果使用到了 Win32 API,则应该使用关键字...__stdcall 在将 C++ 生成的 DLL 供标准C语言使用时,输出文件需要用 extern "C" 修饰,否则不能标准C语言调用。

98370

操作系统概念学习笔记 9 线程

因为任意时刻只能有一个线程能够访问内核,多个线程不能并行运行在多处理器上。 ? 一对一模型: 一对一模型每个用户线程映射到一个内核线程。该模型在一个线程执行阻塞系统调用时,能允许另一个线程继续执行。...目前使用的三种主要的线程库是: (1)POSIX Pthread (2)Win32 (3)Java Pthread作为POSIX标准扩展,可以提供用户级或内核级的库。...然而,由于大多数JVM实例运行在宿主操作系统之上,Java线程API通常采用宿主系统上的线程库来实现。 Pthread Pthread是由POSIX标准线程创建和同步定义的API。...Win32线程Win32 API必须包括windows.h头文件 线程的创建使用了CreateThread() 将一组线程的属性传递给此函数。...当一个类执行runnable()时,他必须定义run()函数实现run()函数的代码被作为一个独立的线程执行

51820

Java 线程和操作系统的线程有啥区别?

操作系统线程 ① 在用户空间中实现线程 在早期的操作系统中,所有的线程都是在用户空间下实现的,操作系统只能看到线程所属的进程,不能看到线程。 ?...线程库就是为开发人员提供创建和管理线程的一套 API。 当然,线程库不仅可以在用户空间中实现,还可以在内核空间中实现。前者涉及仅在用户空间内实现的 API 函数,没有内核支持。...后者涉及系统调用,也就是说调用库中的一个 API 函数将会导致对内核的系统调用,并且需要具有线程库支持的内核。...下面简单介绍下三个主要的线程库: 1)POSIX Pthreads:可以作为用户或内核库提供,作为 POSIX 标准的扩展 2)Win32 线程:用于 Window 操作系统的内核级线程库 3)Java...线程:Java 线程 API 通常采用宿主系统的线程库来实现,也就是说在 Win 系统上,Java 线程 API 通常采用 Win API 来实现,在 UNIX 类系统上,采用 Pthread 来实现

3.9K42

秒杀多线程第二篇 多线程第一次亲密接触 CreateThread与_beginthreadex本质区别

第二个参数表示线程栈空间大小。传入0表示使用默认大小(1MB)。 第三个参数表示新线程执行线程函数地址,多个线程可以使用同一个函数地址。 第四个参数是传给线程函数的参数。...比如标准C运行库的全局变量errno。很多运行库中的函数在出错时会将错误代号赋值给这个全局变量,这样可以方便调试。...//错误处理代码 } } 假设某个线程A在执行上面的代码,该线程在调用system()之后且尚未调用switch()语句时另外一个线程B启动了,这个线程B也调用了标准C运行库的函数,不幸的是这个函数执行出错了并将错误代号写入全局变量...这样每个线程就只会访问和修改自己的数据不会去篡改其它线程的数据了。因此,如果在代码中有使用标准C运行库中的函数时,尽量使用_beginthreadex()来代替CreateThread()。...能不能来一个线程报数功能,即第一个子线程输出1,第二个子线程输出2,第三个子线程输出3,……。要实现这个功能似乎非常简单——每个子线程对一个全局变量进行递增并输出就可以了。

24120

【Chromium】Base库的ThreadPool

TaskExecutor:TaskExecutor可以执行具有特定TaskTraits扩展ID的任务。...注意: 线程池的接口和静态方法,用于管理 post_task.h API 使用的实例。 线程池在调用 Start() 之前不会创建线程。任务可以随时发布,但直到调用 Start() 后才会运行。...该类的实例方法是线程安全的。 除了进程的一个调用点管理进程的实例之外,所有线程池的用户都应该通过 base/task/post_task.h 不是通过这个接口。...这个机制可以用来控制任务的执行时机,例如在某些情况下需要暂时暂停任务的执行,或者在执行一些关键操作时需要确保没有其他任务被调度。...|flush_callback| 可以在任何线程上被调用,不应执行大量的工作。 // 当需要在刷新期间执行当前线程上的其他工作时,可以使用此方法。

14110

Pc软件开发,aardio学习笔记,持续记录

this是类内部指向当前创建对象的指针,this指针不会因为函数的table前缀改变改变。owner对象是会根据函数调用时函数名前缀的table对象相应改变。...win.loopMessage就检索这些消息并将之分发给窗口函数(消息回调函数wndproc、以及事件函数oncommand) 在一个GUI线程(窗口线程)中只能启动一次win.loopMessage...publish("__/*发布消息名*/"),在当前线程内发布消息 subscribe,订阅消息设置回调 tostring,对象转字符串 标准库 1.win win 库主要提供 Windows 系统函数...,延时指定时间执行线程,导入 win 库的界面线程内会执行 win.delay,否则执行 sleep 函数。...thread.waitClose(),等待指定线程句柄的线程运行结束,并释放句柄 8.thread.command 线程创建虽然传递的是闭包,但是不能引用外部的变量,线程有着自己单独的作用域,可以将外部函数挂载到

45730

我是一个线程(节选)

C库也提供了一套用于创建线程函数(当然这个函数底层还是调用相应的操作系统平台的线程创建API),这里之所以提到这点是因为,由于C库函数是同时被Linux和Windows等操作系统支持的,所以使用C库函数创建线程可以直接写出跨平台的代码...新的C++11标准引起了一个新的类std::thread(需要包含头文件),使用这个类的可以将任何签名形式的函数作为线程函数。...如果使用C++面向对象的方式对线程函数进行封装,那么线程函数不能是类的实例方法,即必须是静态方法。那么,为什么不能是类的实例方法呢?...因此如果一个线程函数作为类方法,只能是静态方法不能是实例方法。...其中InitInstance和ExitInstance方法为虚函数,在继承CThread的子类中可以改写这两个方法,根据实际需要在线程函数正式业务逻辑前后做一些初始化和反初始化工作,纯虚接口Run方法必须改写

2.1K40

WPF 的 Dispatcher 为什么要创建一个隐藏窗口?

既然如此,Invoke 相关的自定义消息也可以发给这个线程的消息队列(不是发给特定的窗口),这样也不会漏掉任何消息。也就是说,不需要创建任何窗口也能收到并处理所需的任何消息。...虽然不能正面证明前面 WPF 创建隐藏消息窗口的必要性,但可以知道这至少是一个常用做法。既然常用,那一定有其存在的必要性。...作为一般规则,与窗口不关联的消息不能由 DispatchMessage 函数调度。 因此,如果收件人线程处于模式循环中, (MessageBox 或 DialogBox) ,则消息将丢失。...看起来这是在描述一个现象:如果我们不使用隐藏的消息窗口而是直接将消息发给线程,那么此消息将在线程处于模态时丢失。可是,为什么会丢失呢?...开发者们为什么要自己去开消息循环呢?这不就是众所周知的“模态”吗???弹模态对话框的本质就是开了一个新的消息循环处理消息的同时,阻塞原来的消息循环。

20020

《现代操作系统》—— 线程

线程和进程的区别是进程有独立的地址空间,线程没有。一个进程内的地址空间是其内部的所有控制线程所共享的,这也是为什么开发者要了解资源竞争、加锁、解锁、死锁等线程问题的原因之一。...线程中有: 程序计数器(PC):用于记录接下来要执行哪一条指令 寄存器:用来保存线程当前的工作变量 堆栈:用来记录函数执行历史,其中每一帧记录一个已调用的但还没有从中返回的过程(函数) 尽管,线程必须要在某个进程中执行...它基本上是Portable Operating System Interface(可移植操作系统接口)的缩写,X则表明其对Unix API的传承。...所以pthread是基于某种可移植的线程标准(IEEE的线程标准)定义的线程包。这也是为什么大部分UNIX系统都支持pthread的原因。因为它们都支持这一标准。...这个标准定义了超过60个函数调用,主要的函数如下: 线程调用 描述 pthread_create 创建一个新线程 pthread_exit 结束调用的线程 pthread_join 等待一个特定的线程退出

83910

深入浅出MFC-读书笔记

什么是C Runtime函数库的多线程版本 当C runtime 函数库于1970s 年代产生出来时, PC 的内存容量还很小,多任务是个新奇观念,更别提什么多执行线程了,所以早期只有静态库,重新开发一套支持多执行线程的...runtime 函数库,可能导至程序代码大小和执行效率都遭受不良波及– 即使你只激活了一个执行线程。...事实上执行线程才是排程单位 核心对象 你可以说核心对象是系统的一种资源(噢,这说法对GDI 对象也适用),系统对象一旦产生,任何应用程序都可以开启并使用该对象。...建立新进程之前,系统必须做出两个核心对象,也就是「进程对象」和「执行线程对象」。 只要你有某个进程的handle,就可以结束它的生命。...抽象类别不能产生出对象实体,但是我们可以拥有指向抽象类别之指针,以便于操作抽象类别的各个衍生类别。 7. 虚拟函数衍生下去仍为虚拟函数,而且可以省略virtual 关键词。

78620

Python 高级编程

它是一种比线程更加轻量级的存在,协程不被操作系统内核所管理,完全由程序员自己去控制和调度,带来的好处就是性能得到了很大的提升,不会像线程切换那样消耗资源 ?...同步IO下系统需要切换线程,让操作系统可以在IO过程中执行其他的东西。 这样虽然代码是符合人类的思维习惯但是由于大量的线程切换带来了大量的性能的浪费,尤其是IO密集型的程序。 所以人们发明了异步IO。...通常函数也是一种对象,其中存放了一段等待执行的指令,函数名也是变量,故函数可以赋值给变量,因此函数可以作为返回值 1 >>> def add(): 2 ......写扩展,详见我的博客 调用系统API 通过ctypes模块可以直接调用到操作系统API 如下示例,调用Windows系统中的user32.dll库中的mouse_event函数,移动当前屏幕鼠标箭头的位置...1 python -m pip install pywin32 该库主要有三个模块win32apiwin32gui和win32con Windows API编程示例 1 import win32gui

1.3K70

进程注入1:通过LoadLibrary注入DLL

进程注入是将任意代码写入已经运行的进程中并执行可以用来逃避检测对目标目标进程中的敏感信息进行读/写/执行访问,还可以更改该进程的行为。...Dll不能直接运行,应用在从DLL调用函数的方法之一是通过运行时动态链接,即将DLL加载到程序的进程空间中以便可以调用其导出的函数时。...如果进程已经通过调用LoadLibrary或LoadLibraryEx调用了DLL,没有相应地调用FreeLibrary函数,则不调用入口点函数。...如果DLL使用DllMain函数对进程的每个线程执行初始化,则运行时动态链接可能会导致问题,因为对于调用LoadLibrary或LoadLibraryEx之前存在的线程,不会调用入口点。...DLL可以利用此机会来调用TlsFree函数,以释放通过使用TlsAlloc分配的所有TLS索引,并释放任何线程本地数据。

2.3K30

线程编程10个例子--1

三、Win32 API对多线程编程的支持   Win32 提供了一系列的API函数来完成线程的创建、挂起、恢复、终结以及通信等工作。下面将选取其中的一些重要函数进行说明。...但对于Win32的API编程而言,这两种线程是没有区别的,它们都 只需线程的启动地址即可启动线程执行任务。   ...一般情况下,返回0表明执行成功。 pParam:传递给线程函数的一个32位参数,执行函数将用某种方式解释该值。它可以是数值,或是指向一个结构的指针,甚至可以被忽略; nPriority:线程的优先级。...参数和API函数CreateThread中的对应参数有相同含义,该函数执行成功,返回 非0值,否则返回0。   ...基于Win32的 应用程序执行代码小巧,运行效率高,但要求程序员编写的代码较多,且需要管理系统提供给程序的所有资源;基于MFC类库的应用程序可以 快速建立起应用程序,类库为程序员提供了大量的封装类,而且

2.5K50

Web Worker详解

之所以设置单线程的理论就是,客户端的JavaScript的函数不能运行太长时间,否则会导致循环事件,Web浏览器无法对用户输入做出响应,这也是为什么AJAX的API都是异步的,以及为什么客户端Javascript...不能使用一个简单的异步load()或者require()函数来加载javascript库。...在Web Worker标准中,定义了解决客户端JavaScript无法多线程的问题,其中定义的 ” Worker ” 是指执行代码的并行线程,不过,Web Worker处在一个自包含的执行环境中,无法访问...worker的脚本叫做主线程被创建的新的worker叫做子线程。...web worker是在后台运行的脚本,和其它脚本是独立的,不会影响页面的执行.当web worker在后台运行时你可以继续做你想做的:单击,选择之类的操作 版权声明:本文内容由互联网用户自发贡献

54220

UE4UE5的TaskGraph

本质是程序主动让出CPU的执行权,让CPU可以有机会去执行别的线程或者休息。UE中的锁,事件,Sleep函数等都会产生阻塞。...事件是让业务程序可以主动的阻塞当前线程,或者主动的去唤醒其他线程不用考虑是否进入了某段区域。UE封装成了FEvent对象,对象上有两个函数,Wait函数会阻塞,Trigger会唤醒。...就是一个lambda,第一个参数分为这样几种: Thread,通过创建独立的线程执行Task,也可以直接使用AsyncThread函数 TaskGraph,通过TaskGraph来执行Task,也可以使用...AsyncTask函数 TaskGraphMainThread,也是TaskGraph来执行Task,但是会在主线程执行 ThreadPool,通过线程池来执行Task,也可以使用AsyncPool函数...Groups - Win32 apps | Microsoft Docs 前面这部分很简单,其实就是根据队列顺序依次消费Task来执行TaskGraph最强大的地方在于不同的Task之间可以设置先决条件

5.1K31

dotnet 读 WPF 源代码 聊聊 DispatcherTimer 的实现

在 Windows 上提供了 SetTimer 这个放在 User32.dll 的函数,通过这个 Win32 方法可以调用 Windows 提供的底层定时器的功能 写过 Win32 代码的小伙伴就知道,...刚好咱选用的 SetTimer 是发送窗口消息,自然就是被主线程收到了,咱也就不需要去尝试解决后台线程的计时器需要调度到主线程 对于上层的 API 封装呢?...通过 SetTimer 这个 Win32 函数进行定时,在 Dispatcher 收到 WM_Timer 消息时,如果知道是需要调用哪个 DispatcherTimer 来执行?...从原来的等待 10 秒,判断距离现在还有 5 秒才执行新加入的等待 1 秒的计时器,在接下来的 1 秒就需要执行,那么就需要更新 Win32 计时器,修改定时时间 如果原有一个是定时是 10 秒的计时器在启动了...接下来运行了 9 秒,我再加入一个需要等 3 秒的计时器,显然新加入的计时器还需要等待 3 秒才执行原有的计时器,只需要再等待 1 秒就足够 10 秒了,可以执行

63430

【C++11】std::async函数介绍及问题梳理

是 C++11 标准库中用于异步执行函数,会返回一个 std::future 对象,以获取函数执行结果。...可用其在新线程执行函数,也可以在当前线程执行。std::async 的函数声明形式通常如下: template <typename F, typename......如果任务在新线程执行,并且在该新线程中发生了内存分配失败,那么系统会终止整个程序,不是将异常传递回调用 std::async 的地方【这是因为线程的异常不能线程传递】 这是因为C++的异常处理机制不能线程传播...所以,虽然劫持 new 可以模拟内存不足的情况,但由于异常处理机制的限制,std::async 并不能捕获由于新线程中的内存分配失败导致的异常。...这就是为什么在 main 函数中的 try-catch 块中可以捕获到 std::bad_alloc 异常。 补充说明: std::async 为什么会调用多次new?

35310
领券