简体   繁体   English

如何访问2个线程之间的共享资源?

[英]how to access shared resource between 2 threads?

In one of Outlook add in, I have a worker thread that does some processing and then updates a boolean flag. 在Outlook外接程序中,我有一个工作线程,该线程执行一些处理,然后更新一个布尔标志。 Main thread checks this flag and if this is false , it just process a while loop and does nothing. 主线程检查此标志,如果为false,则仅处理while循环,不执行任何操作。

//worker thread 
void DoSoneThing()
{
Outlook.Recipients recps = mail.Recipients.
foreach(Outlook.Recipient recp in recps)
{
//Save each recipients in a colection
}
isDone=true;
}


//Main thread
while(!isDone)
{
//read the collection where recipients name have been stored.
}``

if the Main thread comes to this piece of code before the worker thread has set the flag to true, main thread keeps on processing the loop and secondry thread is just kind of paused. 如果主线程在工作线程将标志设置为true之前进入这段代码,则主线程将继续处理循环,而第二线程只是处于某种暂停状态。 and since the isDone flag is never set to true, main thread doesn't do any thing. 而且由于isDone标志永远不会设置为true,因此主线程不会执行任何操作。

When I put a lock in the DoSomeThing method and used the same lock in mian thread, this issue is resolved. 当我在DoSomeThing方法中放置锁并在线程中使用相同的锁时,此问题已解决。

myClass
{
public static object _syncRoot = new Object();
void DoSoneThing()
{
lock(_syncRoot)
{
//process 
isDone=true;
}
}
}

myOtherClass
{
    lock(myClass._syncRoot)
{
//process
}
}

My understanding was that lock is used to restrict the entry to same piece of code by more than one thread. 我的理解是,锁用于通过多个线程将输入限制为同一段代码。 But don't understand why worker thread doesn't do any thing when shared resource is accessed by main thread. 但是不明白为什么当主线程访问共享资源时,工作线程不执行任何操作。

I think there is likely to be a slight conceptual problem here. 我认为这里可能存在一些概念上的问题。

Firstly can I suggest that the 首先,我可以建议

while(!isDone)

is not a great way of waiting - It's known as 'spinning' and allows the thread to use processor time when it's not doing anything, which is not efficient. 这不是等待的好方法-这被称为“旋转”,它允许线程在不执行任何操作时占用处理器时间,这效率不高。 (Spinning on a lock can be ok in some specific circumstances, but in a user app is generally not a good plan.) (在某些特定情况下,旋转锁是可以的,但是在用户应用中通常不是一个好计划。)

The lock, making one thread wait while the other processes is much better. 锁,使一个线程等待其他进程更好。

Now, as to your specific problem. 现在,关于您的特定问题。 It's possible that the isDone flag read in the while test has been optimised out (ie the compiler 'knows' that it isn't going to change, so it doesn't put in any code to get it from memory again - it just tests the same CPU register.) You can overcome this by using the 'volatile' modifier to tell the compiler it must re-get the value from memory. while测试中读取的isDone标志可能已被优化(例如,编译器“知道”它不会更改,因此它不会放入任何代码来再次从内存中获取它-它只是进行测试)可以通过使用'volatile'修饰符告诉编译器必须从内存中重新获取值来克服此问题。 It's also possible that the main thread, spinning, is starving the other thread so it never gets a chance to set the flag (although one would hope it would eventually, in a 'fair' system.) 主线程(正在旋转)也可能正在使另一个线程处于饥饿状态,因此它永远都没有机会设置标志(尽管人们希望它最终会在一个“公平”的系统中)。

Regardless of the latter, having a thread spin while waiting for another thread to finish proccessing is to be avoided, unless having checked the flag, it goes off to do something useful (such as updating the GUI) instead. 不管后者如何,都应避免在等待另一个线程完成处理的过程中发生线程旋转,除非检查了该标志,否则它会做一些有用的事情(例如更新GUI)。

You need to be very careful with multi-threaded designs - they're intricate and can have obscure and hard-to-predict behaviour (but are well worth doing for the right circumstances.) 对于多线程设计,您需要非常小心-它们复杂且可能具有模糊且难以预测的行为(但在正确的情况下值得这样做)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM