这篇文章主要围绕多线程–在单个应用程序中调用多个线程的dll函数是否安全?和多个线程调用同一个方法展开,旨在为您提供一份详细的参考资料。我们将全面介绍多线程–在单个应用程序中调用多个线程的dll函数是
这篇文章主要围绕多线程 – 在单个应用程序中调用多个线程的dll函数是否安全?和多个线程调用同一个方法展开,旨在为您提供一份详细的参考资料。我们将全面介绍多线程 – 在单个应用程序中调用多个线程的dll函数是否安全?的优缺点,解答多个线程调用同一个方法的相关问题,同时也会为您带来c – 从另一个线程调用CFRunLoopStop是否安全?、c – 从多个线程读取int是否安全?、c – 在被另一个线程写入并在该线程加入之后从主线程访问变量是否安全?、c – 我是否需要加入我的应用程序中的每个线程?的实用方法。
本文目录一览:- 多线程 – 在单个应用程序中调用多个线程的dll函数是否安全?(多个线程调用同一个方法)
- c – 从另一个线程调用CFRunLoopStop是否安全?
- c – 从多个线程读取int是否安全?
- c – 在被另一个线程写入并在该线程加入之后从主线程访问变量是否安全?
- c – 我是否需要加入我的应用程序中的每个线程?
多线程 – 在单个应用程序中调用多个线程的dll函数是否安全?(多个线程调用同一个方法)
在服务器线程(连接)之间没有任何形式的同步访问dll是否安全?
解决方法
是的,通常可以从多个线程调用DLL函数,因为每个线程都有自己的堆栈,并且调用一个DLL函数或多或少与调用其他代码的其他函数一样.
长答案:
如果实际上可能取决于使用共享可变状态的DLL函数.
例如,如果你这样做:
DLL_SetUser(UserName,Password) if DLL_IsAuthenticated then begin ... end;
那么从不同的线程使用是绝对不安全的.在这个例子中,你不能保证在DLL_SetUser和DLL_IsAuthenticated之间没有其他线程对DLL_SetUser进行不同的调用.
但是,如果DLL函数不依赖某种预定义状态,即所有必需的参数都可以一次使用,所有其他配置对于所有线程都是相同的,那么您可以假设它可以工作.
if DLL_IsAuthenticated(UserName,Password) then begin ... end;
但要小心:可能DLL函数看起来是原子的,但内部使用的是不是的.例如,如果DLL创建一个总是具有相同名称的临时文件,或者访问一次只能处理一个请求的数据库,它将被视为共享状态. (对不起,我想不出更好的例子)
概要:
如果DLL厂商说,他们的DLL是线程安全的,我会使用它们从多个线程没有锁定.如果他们不是 – 或者即使供应商不知道 – 你应该安全地使用锁定.
至少在遇到性能问题之前.在这种情况下,您可以尝试创建多个应用程序/进程,其中包含您的DLL调用并将其用作代理.
c – 从另一个线程调用CFRunLoopStop是否安全?
当打包并离开时,主线程在子线程的运行循环上调用CFRunLoopStop(),此时CFRunLoopRun()在子线程中返回,子线程退出,主线程(这是阻止等待子线程退出)可以继续.
这似乎有效,但我的问题是:这是一种安全/推荐的方式吗?特别是,从另一个线程调用CFRunLoopStop()容易导致竞争条件?据我所知,Apple的文档对此主题保持沉默.
如果从主线程调用CFRunLoopStop()不是解决方案,那么什么是好的解决方案?我知道我可以让子线程调用CFRunLoopRunInMode()并经常唤醒以检查布尔值或其他东西,但我宁愿不让子线程做任何轮询,如果我可以避免它.
解决方法
In particular,is calling CFRunLoopStop() from another thread [safe]?
这是Run Loop Management所说的:
The functions in Core Foundation are generally thread-safe and can be called from any thread.
也许CFRunLoopStop是安全的.但我确实担心他们使用“一般”这个词.我的规则是:如果Apple没有说它是安全的,你应该假设它不是.
为了安全起见,您可以考虑创建一个运行循环源,将其添加到运行循环中,并在结束线程时发出该信号源的信号.该文档包含自定义运行循环源的示例.
c – 从多个线程读取int是否安全?
并且一个线程正在写入值.
我不关心比赛状况.
只有我关心的是写入和读取int值同时是内存安全吗?
它不会导致任何应用程序崩溃.
解决方法
c – 在被另一个线程写入并在该线程加入之后从主线程访问变量是否安全?
int x = 0;std::thread([&]{ x = 1; }).join();std::cout << x;
变量x可以从两个线程访问,而不使用原子或锁.但是,对join()的调用强制对x的访问是顺序的.
这里需要内存屏障吗?
解决方法
这是与您的代码相关的事件的时间表:
thread 1 -------- | int x = 0; (write 0 to x) | std::thread thread 2 (start thread 2) --------> -------- | | join(); x = 1; (thread 1 suspended) (write 1 to x) . | . thread 2 returns . | (thread 1 resumes) <------- x | std::cout << x; (read from x) | thread 1 returns | x
正如您所看到的,x不会被多个线程访问.实际上,join()的使用有效地使得对x的所有访问都按顺序发生,正如您所推测的那样. join()提供同步来代替从锁获得的同步.
基本上,您所拥有的是一个如何使用零并发进行多线程处理的示例.
当然,这只是因为调用join(),这是在您提供的代码片段中创建线程后立即发生的.如果你有这样的事情:
int x = 0;std::thread t([&]{ x = 1; });std::cout << x;t.join(); // Move join() call here
时间轴可能如下所示:
thread 1 -------- | int x = 0; (write 0 to x) | std::thread thread 2 (start thread 2) --------> -------- | | std::cout << x; x = 1; (read from x) (write 1 to x) <-- PROBLEM! | | join(); | (thread 1 suspended) | . | . thread 2 returns . | (thread 1 resumes) <------- x | thread 1 returns | x
以这种方式改变join()的顺序将引入一场比赛.
c – 我是否需要加入我的应用程序中的每个线程?
解决方法
如果你启动一个线程,要么你要分离它,要么在程序结束之前加入它,否则这是未定义的行为.
要知道线程需要分离,你需要问自己这个问题:“我希望线程在程序主函数完成后运行吗?”.这里有些例子:
>当您执行File / New时,您创建一个新线程并将其分离:当用户关闭文档时线程将被关闭在这里您不需要加入线程>当您执行蒙特卡罗模拟,某些分布式计算或任何Divide And Conquer类型算法时,您启动所有线程,您需要等待所有结果,以便您可以将它们组合在一起.在这里你明确需要在组合结果之前加入线程
关于多线程 – 在单个应用程序中调用多个线程的dll函数是否安全?和多个线程调用同一个方法的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于c – 从另一个线程调用CFRunLoopStop是否安全?、c – 从多个线程读取int是否安全?、c – 在被另一个线程写入并在该线程加入之后从主线程访问变量是否安全?、c – 我是否需要加入我的应用程序中的每个线程?的相关知识,请在本站寻找。
本文标签: