那里有更快的那种TMultiReadExclusiveWriteSynchronizer吗?FastCode也许吧?
从Windows Vista开始,Microsoft添加了Slim Reader/Writer锁.它的性能比Delphi 好得多TMultiReadExclusiveWriteSynchronizer.不幸的是,它只存在于Windows Vista及更高版本中,这是很少有客户真正拥有的东西.
据推测,Slim Reader/Writer lock在本机中使用的概念可以在本机Delphi代码中重做 - 但有人做过吗?
我有一种情况,即获取和释放锁定TMultiReadExclusiveWriteSynchronizer(即使没有争用 - 单个线程),导致100%的开销(操作时间加倍).我可以在没有锁定的情况下运行,但是我的类不再是线程安全的.
有更快的TMultiReadExclusiveWriteSynchronizer吗?
注意:如果我使用TCriticalSectioni,只会遭受2%的性能损失(尽管已知关键部分在获取成功时很快,即它是单线程并且没有争用).CS的缺点是我失去了" 多个读者 "的能力.
使用TMultiReadExclusiveWriteSynchronizer相当长的时间在内部BeginRead和EndRead:

然后移植代码以使用Window自己的SlimReaderWriter Lock(其中一些代码重写,因为它不支持递归锁定),并分析了resutls:
TMultiReadExclusiveWriteSynchronizer:每次迭代
10,698 ns 10,697,772,613 ns,迭代1,000,000次
SRWLock:每次迭代
8,802 ns,8,801,678,339 ns,迭代1,000,000次
Omni Reader-Writer lock:每次迭代8,941 ns,
8,940,552,487 ns,迭代1,000,000次
使用SRWLocks(又名Omni的旋转锁)时,性能提高了17%.
现在,我不能永久地切换代码以使用Windows Vista SRWLocks,因为有些客户仍然在Windows XP上.
Slim锁只是小心使用InterlockedCompareExchange功能; 但比我能成功使用更加小心.我 …
delphi multithreading critical-section readerwriterlock readerwriterlockslim
这对我来说似乎很吵.五行开销太多了.
m_Lock.EnterReadLock()
Try
Return m_List.Count
Finally
m_Lock.ExitReadLock()
End Try
Run Code Online (Sandbox Code Playgroud)
那你怎么这么简单呢?
我们有项目目标.NET 2.0 RTM(是的,它应该是.NET 2.0 RTM,我们有一些正统的客户端).而我只是想知道ReaderWriterLock的缺点是什么?为什么每个人都说"不要使用它,尝试使用其他类似lock声明" 这么糟糕?如果我们可以使用.NET 3.5,我肯定会使用ReaderWriterLockSlim,但ReaderWriterLock我对所有这些来自各地的警告都有点害怕.有人测量过表现还是其他什么?如果存在一些性能问题,我们可以在哪些有效负载下遇到它们?
我们在ReaderWriterLock主要目的方面有一个经典的情况,即多次读取和很少写入.使用lock语句会阻止所有读者.也许对我们来说这不是一个可怕的问题,但如果我可以使用,ReaderWriterLock我会更满意.国际海事组织介绍几台显示器确实是一个非常糟糕的主意.
.net c# multithreading readerwriterlock readerwriterlockslim
任何解释每个的实时场景都将受到赞赏.除了pthreads之外还有其他方法来处理同步.互斥体与递归互斥体(任何实时场景)有何不同?
是否存在跨进程工作的读/写锁定机制(类似于Mutex,但是读/写而不是独占锁定)?我想允许并发读访问,但独占写访问.
我正在尝试解决以下问题,我知道有多种解决方案,但我正在寻找最优雅的方法(更少的代码)来解决它。
我有 4 个线程,其中 3 个尝试在无限循环中将唯一值(0、1 或 2)写入易失性整数变量,第四个线程尝试读取此变量的值并将值打印到标准输出也处于无限循环中。
我想在线程之间同步,这样写 0 的线程将被运行,然后是“打印”线程,然后是写 1 的线程,然后是打印线程,依此类推......所以最后我期望在“打印”线程的输出中看到一个零序列,然后是 1 序列,然后是 2,然后是 0 等等......
在这些线程之间同步的最优雅和最简单的方法是什么?
这是程序代码:
volatile int value;
int thid[4];
int main() {
HANDLE handle[4];
for (int ii=0;ii<4;ii++) {
thid[ii]=ii;
handle[ii] = (HANDLE) CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE) ThreadProc, &thid[ii], 0, NULL);
}
return 0;
}
void WINAPI ThreadProc( LPVOID param ) {
int h=*((int*)param);
switch (h) {
case 3:
while(true) {
cout << value << endl;
}
break;
default:
while(true) {
// setting a unique …Run Code Online (Sandbox Code Playgroud) 我有一个IDictionary<TKey,TValue>内部持有另一个的实现,Dictionary<TKey, TValue>并通过密钥的HashCode将插入分发到invidual子字典.有16个子词典,4核机器上的冲突数量相当低.
对于并行插入,我使用a锁定Add-method ReaderWriterLockSlim,仅锁定单个子字典:
public void Add(TKey key, TValue value)
{
int poolIndex = GetPoolIndex(key);
this.locks[poolIndex].EnterWriteLock();
try
{
this.pools[poolIndex].Add(key, value);
}
finally
{
this.locks[poolIndex].ExitWriteLock();
}
}
Run Code Online (Sandbox Code Playgroud)
插入四个线程的项目时,我只有大约32%的CPU使用率和糟糕的性能.所以我用Monitor(即lock关键字)替换了ReaderWriterLockSlim .CPU使用率现在接近100%,性能提高了一倍多.
我的问题是:为什么CPU使用率会增加?碰撞次数不应该改变.是什么让ReaderWriterLock.EnterWriteLock等了这么多次?
有一个作家线程,定期从某个地方收集数据(实时,但这在问题中并不重要)。有很多读者然后从这些数据中读取。通常的解决方案是使用两个读写器锁和两个缓冲区,如下所示:
Writer (case 1):
acquire lock 0
loop
write to current buffer
acquire other lock
free this lock
swap buffers
wait for next period
Run Code Online (Sandbox Code Playgroud)
或者
Writer (case 2):
acquire lock 0
loop
acquire other lock
free this lock
swap buffers
write to current buffer
wait for next period
Run Code Online (Sandbox Code Playgroud)
在这两种方法中,如果获取其他锁操作失败,则不进行交换并且写入器将覆盖其先前的数据(因为写入器是实时的,它无法等待读取器)因此在这种情况下,所有读取器都会丢失该帧数据的。
不过这没什么大不了的,读者是我自己的代码,他们很短,所以有了双缓冲区,这个问题就解决了,如果有问题,我可以把它变成三重缓冲区(或更多)。
问题是我想最小化的延迟。想象案例1:
writer writes to buffer0 reader is reading buffer1
writer can't acquire lock1 because reader is still reading buffer1
| |
| reader finishes reading,
| …Run Code Online (Sandbox Code Playgroud) 您好我需要在我的方法中使用writerreaderlock.我想知道如何正确使用它.
我有一本ObjectA字典
public class ObjectA
{
public ReaderWriterLock RWL {get;set;}
public ObjectB obj {get;set;}
public ObjectA()
{
RWL = new ReaderWriterLock();
}
}
public class ObjectB
{
int TTL {get;set;}
string Value {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
在我的方法中,我使用ObjectA的字典,键是Guid,所以假设当我调用dict [guid]时它总是返回我的ObjectA的一个实例(例如)
public foo()
{
ObjecA objA = dict[guid];
objA.RWL.AcquireReaderLock(500);
if(objA.obj.TTL<=0)
{
objA.obj.RWL.AcquireWriterLock(1000);
objA.obj.Value = DateTime.Now().ToString();
objA.obj.RWL.ReleaseWriterLock();
}else{
int ttl = objA.obj.TTL;
Interlocked.Decrement(ref ttl);
}
objA.RWL.ReleaseReaderLock();
}
Run Code Online (Sandbox Code Playgroud)
我真的不确定我在那边使用读者和作者,我是如何使用读写器锁,条件验证?
这是读者作者的实现,即许多读者可以阅读但只有一个作家可以在任何时候写.这是否按预期工作?
public class ReadersWriters extends Thread{
static int num_readers = 0;
static int writing = 0;
public void read_start() throws InterruptedException {
synchronized(this.getClass()) {
while(writing == 1) wait();
num_readers++;
}
}
public void read_end() {
synchronized(this.getClass()) {
if(--num_readers == 0) notifyAll();
}
}
public void write_start() throws InterruptedException{
synchronized(this.getClass()) {
while(num_readers > 0) wait();
writing = 1;
}
}
public void write_end() {
this.getClass().notifyAll();
}
}
Run Code Online (Sandbox Code Playgroud)
此实现也与声明每个方法有任何不同
public static synchronized read_start()
Run Code Online (Sandbox Code Playgroud)
例如?
谢谢