我需要在Win7 x64上实现与此函数相同的功能。Windows C++等价于Java的LockSupport.parkNanos()
我最初使用SwitchToThread()
但这不起作用,因为它会在极端条件下导致死锁。我能找到的唯一选择是Sleep()
,但这可能是一个性能杀手,因为它只能以毫秒分辨率工作,我仍然不确定它是否与LockSupport.parkNanos()
一样。
我发现Java的计划能力(如果这是发生了什么事情)的线程在纳秒间隔可疑,所以我实现了我只能假设他们做...旋转。然而,我不确定这是否能解决问题,它可能仅仅是推迟了不可避免的,因为看起来Java函数需要JVM的干预才能工作。没有parkNanos
的源代码可用;它在本地Sun库中实现。
class LockSupport
{
public:
static void ParkNanos(unsigned __int64 aNanos)
{
ULONGLONG start;
ULONGLONG end;
::QueryUnbiasedInterruptTime(&start);
do
{
// My issue with this is that nothing is actually 'Parked'.
::SwitchToThread();
::QueryUnbiasedInterruptTime(&end);
}
while ((end - start) < aNanos);
}
};
调用代码看起来是这样的:
void SomeClass::SomeFunction()
{
while (someCond)
{
LockSupport.parkNanos(1L);
}
}
FWIW,我移植LMAX的干扰器模式C++。当一个线程处于SingleThreadedClaimStrategy::WaitForFreeSlotAt()
而另一个线程处于BlockingWaitStrategy::WaitFor
(无超时)时,会发生死锁。当RingBuffer大小很小时,死锁就更加明显...... 1,2,4,8等。
这些线程是由正常的CreateThread
手段创建的。
编辑:当我写这个的时候已经很晚了,所以这里有一些更多的信息。 RingBuffer持有__int64
s。我有一个生产者线程和一个消费者线程。消费者线程还生成一个Timer线程,该线程每秒钟轮询消费者使用它上次使用的事件的序列号。当消费者没有取得进展并且制片人还没有完成时,就有一个问题出现。制片人仅仅是在发行计数器的几百万次循环中运行。所以,我的输出看起来是这样的:
898
97
131
Timer: no progress
Timer: no progress
...
这是唯一真正可重复的发布模式,一切的速度进行了优化。
你说你用':: SwitchToThread()'死锁了。它返回真或假? – Managu 2012-08-16 03:51:47
@Managu在正常执行期间,它可以返回两者。然而,你的评论给了我这个函数旋转的想法,而它返回false。 – James 2012-08-16 12:55:47
你是如何实现ReentrantLock和Condition的,就像BlockingWaitStrategy所使用的那样?你的锁定实现是否可重入?条件变量是否以原子方式获取/释放相应的锁? – Managu 2012-08-17 01:40:21