سؤال

هل هناك آلية قفل قراءة/كتابة تعمل عبر العمليات (على غرار Mutex ، ولكن القراءة/الكتابة بدلاً من ذلك قفل حصري)؟ أرغب في السماح بوصول القراءة المتزامنة ، لكن الوصول الحصري للكتابة.

هل كانت مفيدة؟

المحلول

لا. كما أشار ريتشارد أعلاه ، لا يوجد مثل هذا المربع في .NET. هذه هي كيفية تنفيذها باستخدام mutex و smaphore.

الطريقة رقم 1 موصوفة في http://www.joecheng.com/blog/entries/writinganinter-processrea.html, نقلا عن:

// create or open global mutex
GlobalMutex mutex = new GlobalMutex("IdOfProtectedResource.Mutex");
// create or open global semaphore
int MoreThanMaxNumberOfReadersEver = 100;

GlobalSemaphore semaphore = new GlobalSemaphore("IdOfProtectedResource.Semaphore", MoreThanMaxNumberOfReadersEver);

public void AcquireReadLock()
{
  mutex.Acquire();
  semaphore.Acquire();
  mutex.Release();
}

public void ReleaseReadLock()
{
  semaphore.Release();
}

public void AcquireWriteLock()
{
  mutex.Acquire();
  for (int i = 0; i < MoreThanMaxNumberOfReadersEver; i++)
    semaphore.Acquire(); // drain out all readers-in-progress
  mutex.Release();
}

public void ReleaseWriteLock()
{
  for (int i = 0; i < MoreThanMaxNumberOfReadersEver; i++)
    semaphore.Release();
}

سيكون بديل:

اقرأ القفل - على النحو الوارد أعلاه. اكتب قفلًا على النحو التالي (الكود الكاذب):

- Lock mutex
- Busy loop until the samaphore is not taken AT ALL:
-- wait, release.
-- Release returns value; 
-- if value N-1 then break loop.
-- yield (give up CPU cycle) by using Sleep(1) or alternative
- Do write
- Release mutex

تجدر الإشارة إلى أن النهج الأكثر كفاءة ممكن ، كما هو الحال هنا: http://en.wikipedia.org/wiki/readers-writers_problem#the_second_readers-writers_problemابحث عن عبارة "هذا الحل هو دون المستوى الأمثل" في المقالة أعلاه.

نصائح أخرى

لا يتضمن Windows قفل كاتب القارئ عبر العملية. يمكن استخدام مزيج من الإشارات والموتاة لبناء تلك (يتم الاحتفاظ بالموتاة من قبل كاتب للوصول الحصري أو بواسطة قارئ يستخدم بعد ذلك الإشارة لإطلاق القراء الآخرين - سينتظر الكتاب فقط على Mutex والقراء لأي منهما) .

ومع ذلك ، إذا كان من المتوقع أن يكون الخلاف منخفضًا (أي لا يوجد خيط يحمل قفلًا لفترة طويلة) ، فقد يظل الاستبعاد المتبادل أسرع: التعقيد الإضافي لقفل القارئ يكتسب أي فائدة من السماح للقراء المتعددين في. لن يكون القفل أسرع إلا إذا كان هناك العديد من القراء ويتم الاحتفاظ بأقفال لوقت كبير - لكن فقط يمكن أن يؤكد هذا التوصيف.)

لقد قمت بإنشاء هذا الفصل بناءً على إجابة بافيل. لم أختبرها على نطاق واسع بعد ، لكنني أنشأت تطبيق WinForms بسيط لاختباره وحتى الآن يعمل بشكل جيد.

يرجى ملاحظة ، أنه يستخدم إشارة ، بحيث لا تدعم إعادة التحويل.

public class CrossProcessReaderWriterLock
{
    private readonly string _name;
    const int _maxReaders = 10;

    readonly Mutex     _mutex;
    readonly Semaphore _semaphore;

    public CrossProcessReaderWriterLock(string name)
    {
        _name = name;
        _mutex     = new Mutex(false, name + ".Mutex");
        _semaphore = new Semaphore(_maxReaders, _maxReaders, name + ".Semaphore");
    }

    public void AcquireReaderLock()
    {
        //Log.Info($"{_name} acquiring reader lock...");

        _mutex    .WaitOne();
        _semaphore.WaitOne();
        _mutex    .ReleaseMutex();

        //Log.Info($"{_name} reader lock acquired.");
    }

    public void ReleaseReaderLock()
    {
        _semaphore.Release();

        //Log.Info($"{_name} reader lock released.");
    }

    public void AcquireWriterLock()
    {
        //Log.Info($"{_name} acquiring writer lock...");

        _mutex.WaitOne();

        for (int i = 0; i < _maxReaders; i++)
            _semaphore.WaitOne(); // drain out all readers-in-progress

        _mutex.ReleaseMutex();

        //Log.Info($"{_name} writer lock acquired.");
    }

    public void ReleaseWriterLock()
    {
        for (int i = 0; i < _maxReaders; i++)
            _semaphore.Release();

        //Log.Info($"{_name} writer lock released.");
    }
}

System.Threading.Mutex لديه mutex يمكن استخدامها للاتصال داخل العملية. إذا كنت ترغب في وظيفة لا تدعمها ، فيمكن تنفيذها عبر Mutex.

هل نظرت إلى System.Threading.ReaderWriteLock؟ ها هي MSDN نهاية لهذه الغاية.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top