标签: synchronization

关键部分总是更快吗?

我正在调试一个多线程应用程序,并找到了内部结构CRITICAL_SECTION.我发现LockSemaphoreCRITICAL_SECTION的数据成员很有趣.

它看起来像是LockSemaphore一个自动重置事件(顾名思义不是信号量),并且当第一次线程等待Critcal Section某个其他线程锁定时,操作系统会静默创建此事件.

现在,我想知道关键部分总是更快吗?Event是一个内核对象,每个Critical部分对象都与事件对象相关联,那么Critical Section与其他内核对象(如Mutex)相比,如何更快?此外,内部事件对象如何实际影响Critical部分的性能?

这是结构CRITICAL_SECTION:

struct RTL_CRITICAL_SECTION
{
    PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
    LONG LockCount;
    LONG RecursionCount;
    HANDLE OwningThread;
    HANDLE LockSemaphore;
    ULONG_PTR SpinCount;
};
Run Code Online (Sandbox Code Playgroud)

c++ winapi synchronization critical-section

23
推荐指数
2
解决办法
2万
查看次数

具有多核处理器的关键部分

使用单核处理器,所有线程都从一个CPU运行,在内存中的某些互斥(或信号量等)上使用原子测试和设置操作实现关键部分的想法似乎很简单; 因为你的处理器正在从程序中的一个位置执行测试和设置,所以它一定不能从程序中的另一个位置伪装成其他线程.

但是当你真的拥有多个物理处理器时会发生什么?似乎简单的指令级原子性是不够的,b/c有两个处理器可能同时执行它们的测试和设置操作,你真正需要保持原子性是访问共享内存位置的互斥.(如果共享内存位置被加载到缓存中,那么整个缓存一致性也要处理...)

这似乎比单核案例带来更多的开销,所以问题的关键在于:它有多糟糕?更糟糕吗?我们只是忍受它吗?或者通过强制执行一个策略来回避它,即进程组中的所有线程都必须位于同一个物理核心上?

multithreading synchronization cpu-architecture

23
推荐指数
2
解决办法
7658
查看次数

如何在不同的计算机上同步Chrome扩展程序数据?

我有一个扩展,用户可以在其中维护链接列表.将这些数据在计算机之间同步(在工作和家中)会很好.有哪些可能的解决方案?

Chrome有扩展同步选项,但我不确定它是否同步数据(如果是,我会感到惊讶).即使它确实如此,也不是每个人都希望同步所有其他扩展.

我可以将我的链接存储在一个特殊的书签文件夹中,并使用内置的书签同步,但在这种情况下,所有书签也会同步(并非所有用户都希望我这么想).

我可以使用的任何外部网站?一些易于使用并链接到谷歌帐户?

(我不想为此建立自己的网站)

synchronization google-chrome google-chrome-extension

23
推荐指数
2
解决办法
9759
查看次数

为什么wait/notify/notifyAll方法在java中不同步?

在Java中,每当我们需要调用wait/notify/notifyAll时,我们需要访问对象监视器(通过synchronized方法或通过synchronized块).所以我的问题是为什么java没有去同步等待/通知方法去除从同步块或方法调用这些方法的限制.

如果将它们声明为synchronized,它将自动获取监视器访问权限.

java multithreading synchronization synchronized

23
推荐指数
3
解决办法
5461
查看次数

不明白是否需要Monitor.Pulse()

根据MSDN,Monitor.Wait():

释放对象的锁定并阻止当前线程,直到它重新获取锁定.

但是,我读过的关于Wait()和Pulse()的所有内容似乎表明仅仅在另一个线程上释放锁是不够的.我需要先调用Pulse()来唤醒等待的线程.

我的问题是为什么?在Monitor.Enter()上等待锁的线程只是在它被释放时获取它.没有必要"唤醒他们".它似乎打败了Wait()的用处.

例如.

static object _lock = new Object();

static void Main()
{
    new Thread(Count).Start();
    Sleep(10);

    lock (_lock)
    {
         Console.WriteLine("Main thread grabbed lock");
         Monitor.Pulse(_lock) //Why is this required when we're about to release the lock anyway?
    }
}

static void Count()
{
    lock (_lock)
    { 
        int count = 0;

        while(true)
        {
            Writeline("Count: " + count++);

            //give other threads a chance every 10th iteration
            if (count % 10 == 0)
                 Monitor.Wait(_lock);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我使用Exit()和Enter()而不是Wait(),我可以这样做: …

c# multithreading synchronization

23
推荐指数
3
解决办法
9710
查看次数

在多个设备之间同步JS时间

我正在使用精彩的reveal.js库来创建HTML幻灯片.我唯一的问题是我需要它来跨多个设备进行同步.

目前我正在从服务器发出一个AJAX请求,并保留页面的内部时钟.

function syncTime() {
    // Set up our time object, synced by the HTTP DATE header
    // Fetch the page over JS to get just the headers
    console.log("syncing time")
    var r = new XMLHttpRequest();
    r.open('HEAD', document.location, false);
    r.send(null);
    var timestring = r.getResponseHeader("DATE");

    systemtime = new Date(timestring); // Set the time to the date sent from the server
}
Run Code Online (Sandbox Code Playgroud)

虽然这让我在1秒左右的准确度,但我需要做得更好.幻灯片显示自动前进时,差异非常明显.

代码将在同一平台上运行,因此跨浏览器兼容性无需担心.

这就是我设法组建的内容

有任何想法吗?

javascript time synchronization

23
推荐指数
3
解决办法
1万
查看次数

数学背后谷歌闰第二涂抹公式

谷歌Leap Second Smear Techinque中提到的公式:在午夜前的时间窗口内调节"谎言":

lie(t) = (1.0 - cos(pi * t / w)) / 2.0 
Run Code Online (Sandbox Code Playgroud)

没有描述这背后的数学.有人可以解释为什么公式有效.这也可以用于我们想要在窗口上逐渐同步时间并避免突然跳跃的任何情况吗?

math synchronization timestamp

23
推荐指数
1
解决办法
4239
查看次数

为什么LogicalCallContext无法与异步一起使用?

在这个问题中,Stephen Cleary接受的答案是LogicalCallContext无法正常使用异步.他还在这个 MSDN主题中发布了它.

LogicalCallContext保存一个Hashtable,存储发送到CallContext.LogicalGet/SetData的数据.它只是这个Hashtable的浅层副本.因此,如果您在其中存储可变对象,则不同的任务/线程将看到彼此的更改.这就是Stephen Cleary的示例NDC程序(在MSDN线程上发布)无法正常工作的原因.

但是AFAICS,如果你只在Hashtable中存储不可变数据(可能通过使用不可变集合),那应该有效,让我们实现一个NDC.

然而,Stephen Cleary也在接受的答案中说:

CallContext不能用于此.Microsoft特别建议不要使用CallContext进行远程处理以外的任何操作.更重要的是,逻辑CallContext不了解异步方法如何早期返回并稍后恢复.

不幸的是,该建议的链接已关闭(找不到页面).所以我的问题是,为什么不推荐这个?为什么我不能以这种方式使用LogicalCallContext?说它不理解异步方法是什么意思?从调用者的POV,他们只是返回任务的方法,不是吗?

ETA:另见其他问题.在那里,Stephen Cleary的答案说:

你可以使用CallContext.LogicalSetData和CallContext.LogicalGetData,但我建议你不要,因为当你使用简单的并行性时它们不支持任何类型的"克隆"

这似乎支持我的情况.所以我应该能够建立一个NDC,这实际上是我需要的,而不是log4net.

我写了一些示例代码,它似乎工作,但仅仅测试并不总是捕获并发错误.所以,由于其他帖子中有提示这可能不起作用,我仍然会问:这种方法有效吗?

ETA:当我从下面的答案中运行斯蒂芬提出的复制品时,我没有得到错误的答案,他说我会,我得到正确的答案.即使他说"这里的LogicalCallContext值总是"1"",我总是得到0的正确值.这可能是因为竞争条件?无论如何,我还没有在我自己的电脑上复制任何实际问题.这是我正在运行的确切代码; 它只在这里打印"真实",斯蒂芬说至少在某些时候应该打印"假".

private static string key2 = "key2";
private static int Storage2 { 
    get { return (int) CallContext.LogicalGetData(key2); } 
    set { CallContext.LogicalSetData(key2, value);} 
}

private static async Task ParentAsync() {
  //Storage = new Stored(0); // Set LogicalCallContext value to "0".
  Storage2 = 0;

  Task childTaskA = ChildAAsync();
  // LogicalCallContext value here is always …
Run Code Online (Sandbox Code Playgroud)

.net c# synchronization task-parallel-library async-await

23
推荐指数
2
解决办法
1万
查看次数

如何正确使用sync.Cond?

我无法弄清楚如何正确使用sync.Cond.据我所知,在锁定Locker和调用条件的Wait方法之间存在竞争条件.此示例在主goroutine中的两条线之间添加了一个人工延迟来模拟竞争条件:

package main

import (
    "sync"
    "time"
)

func main() {
    m := sync.Mutex{}
    c := sync.NewCond(&m)
    go func() {
        time.Sleep(1 * time.Second)
        c.Broadcast()
    }()
    m.Lock()
    time.Sleep(2 * time.Second)
    c.Wait()
}
Run Code Online (Sandbox Code Playgroud)

[ 在游乐场跑步 ]

这会立即引起恐慌:

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [semacquire]:
sync.runtime_Syncsemacquire(0x10330208, 0x1)
    /usr/local/go/src/runtime/sema.go:241 +0x2e0
sync.(*Cond).Wait(0x10330200, 0x0)
    /usr/local/go/src/sync/cond.go:63 +0xe0
main.main()
    /tmp/sandbox301865429/main.go:17 +0x1a0

我究竟做错了什么?我该如何避免这种明显的竞争状况?我应该使用更好的同步构造吗?


编辑:我意识到我应该更好地解释我想在这里解决的问题.我有一个长期运行的goroutine,下载一个大文件和许多其他goroutine,当它们可用时需要访问HTTP标头.这个问题比听起来更难.

我不能使用频道,因为只有一个goroutine会收到该值.而其他一些goroutine将在它们已经可用之后很久就试图检索它们.

下载程序goroutine可以简单地将HTTP标头存储在变量中,并使用互斥锁来保护对它们的访问.但是,这并没有为其他goroutines提供"等待"它们可用的方法.

我曾经想过,一个sync.Mutex人和一个人sync.Cond都可以完成这个目标,但似乎这是不可能的.

synchronization go race-condition

23
推荐指数
3
解决办法
1万
查看次数

如何以及何时在Julia中使用@async和@sync

我已经阅读了和宏的文档,但仍然无法弄清楚如何以及何时使用它们,也无法在互联网上的其他地方找到许多资源或示例. @async@sync

我的直接目标是找到一种方法来设置几个工作程序并行工作,然后等待它们全部完成后继续我的代码.这篇文章:等待在Julia的远程处理器上完成的任务包含一个成功的方法来实现这一点.我原以为应该可以使用@async@sync宏,但是我最初的失败让我想知道我是否正确理解了如何以及何时使用这些宏.

parallel-processing macros synchronization asynchronous julia

23
推荐指数
1
解决办法
6383
查看次数