C#中忙碌等待的一个简单例子

时间:2015-03-10 12:17:23

标签: c#

我正在学习 C#语言,我是初学者。

我想通过使用 C#语言中的线程来实现忙碌等待。

我之前已阅读过链接,但有一个 C语言示例代码:

http://en.wikipedia.org/wiki/Busy_waiting

2 个答案:

答案 0 :(得分:5)

您提供的链接几乎可以直接转换为C#。忙等待(或自旋锁)在void *f1(void *p)中实现。这可以转换为C#,因此:

static void f1()
{
    while (i == 0)
    {
    }

    Console.WriteLine("i's value has changed to {0}.", i);
    return;
}

我建议不要使用手工制作的旋锁,除非你完全确定你在做什么。如果您需要对变量进行独占访问,请使用lock关键字标记使用该变量的关键代码段。

Joe Albahari发布了excellent and free introduction to threading。我强烈建议您阅读本文以更好地理解线程和线程同步。

答案 1 :(得分:3)

所以pixelbadger已经为你发布了一个实际的自旋锁代码。请注意,这会使您的CPU使用率提高到100%,因为您的while循环只是尽可能快。 (根据我对它们的理解,这是所有自旋锁的问题。我从来不知道它们的名字。)

首选方法是在值更改时收到通知。为此,请看一下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Sandbox
{
    class Program
    {
        // some random object to lock on
        private static Object objLock;

        // the value we want to read
        private static int value;

        // entry point
        static void Main(string[] args)
        {
            value = 0;
            objLock = new Object();

            // Backgrond worker runs on a new thread.
            BackgroundWorker bgw = new BackgroundWorker();
            // tells the background worker object that when it is run, it should execute the bgw_DoWork method below.
            bgw.DoWork += bgw_DoWork;
            // runs the background worker
            bgw.RunWorkerAsync();

            getValue();
            Console.ReadKey();
        }

        private static void getValue()
        {
            // lock on our lock object so that no other thread can execute code that locks on the same object
            lock (objLock)
            {
                // Relinquishes the lock on our lock object.  This thread starts blocking ("paused")
                Monitor.Wait(objLock);
            }
            // Since the monitor Pulse(), we can continue execution.

            Console.WriteLine(value); // prints out 10 after the 2 second delay
        }

        static void bgw_DoWork(object sender, DoWorkEventArgs e)
        {
            System.Threading.Thread.Sleep(2000); // some long operation that calculates the new value
            // this locks on our lock object.  since we Wait() on the objlock in getValue(), the lock is available and we
            // can continue executing this code.
            lock (objLock)
            {
                value = 10;
                // This tells the thread executing getValue() that it may continue.
                Monitor.Pulse(objLock);
            }
        }
    }
}

重申一下,这不是一个自旋锁,但应该完成相同的结果。