PrintHello()
函数pthreads示例是否是线程安全的?我在网上找到了这些例子,但我不明白它们如何是线程安全的。另一方面,如果我在PrintHello()
函数中的代码周围添加一个互斥锁,那么该示例将不会是多线程的,因为所有线程都会排队等待前一个线程退出PrintHello()
函数。此外,将它移动到一个类也无济于事,因为成员必须被静态声明为非{1}}似乎不允许指向非静态函数的指针。有什么方法可以解决这个问题吗?
CreateThread()
答案 0 :(得分:6)
由于您要包含WinBase.h
,我会假设您使用的是MSVC。 MSVC CRT长期以来一直支持多线程访问 - 事实上,当前版本的MSVC不再支持不是线程安全的单线程CRT。我相信VS 2003是支持单线程CRT的MSVC的最后一个版本。
在多线程CRT中,函数是线程安全的,如果它们在内部访问全局数据,它们将在它们之间同步。因此,printf()
中执行的每个ProcessRequest()
在其他线程中与其他printf()
调用相比将是原子的(实际上,锁是基于流的,因此printf()
调用将是相对于使用stdout
)的其他CRT函数的原子。
例外情况是,如果您使用明确记录的I / O函数不带锁(因此您可以出于性能原因自行同步),或者如果您定义_CRT_DISABLE_PERFCRIT_LOCKS
,则在这种情况下使用CRT假设所有I / O都将在一个线程上执行。
请参阅http://msdn.microsoft.com/en-us/library/ms235505.aspx
POSIX做出类似的保证printf()
将是线程安全的:
http://pubs.opengroup.org/onlinepubs/9699919799/functions/flockfile.html
引用(FILE *)对象的所有函数(名称以_unlocked结尾的函数除外)的行为应该像在内部使用flockfile()和funlockfile()来获取这些(FILE *)对象的所有权一样。
http://newsgroups.derkeiler.com/Archive/Comp/comp.programming.threads/2009-06/msg00058.html(David Butenhof的帖子):
POSIX / UNIX要求printf()本身是原子的;从不同的线程对printf()的两个并行调用可以混合它们的数据是不合法的。但是这两个写入可能以任何顺序出现在输出中。
答案 1 :(得分:0)
代码一般不是线程安全的; printf
通常不是
折返。 (一个实现可以添加reentrace作为
一个额外的功能,但我不知道有哪些功能。)你
必须在它周围添加某种保护。 (在Windows下,
一个所谓的CriticalSection
就足够了。)
您还必须找到sleep
的线程安全替代方案;
我找不到任何说它是可重入的文档
(并没有Posix变体),但微软似乎没有
文件再入一般。这是一个经典的解决方案
将创建一个Mutex,阻止它,然后调用
WaitForSingleObject
上有所需的超时时间;
CreateWaitableTimer
和WaitForSingleObject
应该有效
好。 (正如我所说,微软的文档非常缺乏;
但是WaitForSingleObject
必须是安全的,因为它被设计为
在等待互斥锁等时使用。)
另请注意,除非您加入创建的主题,否则您将会这样做
可能会在main
结束时运行,并且过程将会发生
在任何线程运行之前终止。 (下
Windows,您可以使用WaitForSingleObject
或
WaitForMultipleObjects
加入。)
如果你有更好的解决方案,那就是标准线程 如果你有一个支持它们的编译器,或者Boost threds 不。