2009-08-25 14 views
6

ı Sonra diyelim ki şu koduKilitli FIFO üzerinde bekleyen iş parçacıkları var mı?

static class ... 
{ 
    static object myobj = new object(); 

    static void mymethod() 
    { 
     lock(myobj) 
     { 
      // my code.... 
     } 
    } 
} 

var diyelim o thread1 myMethod çalıştırmayı dener thread2 kilidi varken. Kilidin serbest bırakılmasını veya bir istisna atmasını bekleyecek mi?

Eğer beklerse, ek dişler gelirse FIFO olur mu?

cevap

8

Benim yanıtım güncelleştirildi: Sıraya alındı, ancak siparişin FIFO olması garanti edilmiyor. Bu bağlantıyı dışarı

Kontrol: http://www.albahari.com/threading/part2.aspx

+4

Mutlaka bkz. Http://stackoverflow.com/questions/961869/is-there-a-synchronization-class-that-guarantee-fifo-order-in-c/961904 –

-1

O bekleyecek ve bunlar aynı sırada olmayacaktır. Eğer başka bir ReaderWriterLock falan gibi bir şey bakarsak

ihtiyaçlarınıza bağlı olarak, sadece lock

+1

Aynı şey değiller. sipariş. –

3

O myobjmymethod içeride görünür olmasını alıyor nasıl kodundan belli değil daha performansa sahip olabilir. Görünüşe göre var myobj, bildirim kapsamındaki yerel bir yığın değişkeni (var olduğundan). Bu durumda, her bir iş parçacığının ayrı bir örneğinin olması ve mymethod'un engellenmeyeceği olabilir.

bütün FIFO argüman Hakkında Güncelleme

, bazı arka plan bilgisi gereklidir: CLR senkronizasyonu sağlamaz. CLR çalışma zamanına hizmeti hizmeti sağlayan CLR ana bilgisayarı'dur. Ev sahibi, IHostSyncManager ve diğer arabirimleri uygular ve çeşitli eşitleme ilkelerini sağlar. Bu, en yaygın ana bilgisayar tipik uygulama ana bilgisayarı (yani, derleme ve exe) ve bu işletim sisteminin tüm senkronizasyonunu (Win32 API'daki eski Petzold kitap ilkelleriniz) engeller. Ancak en az iki büyük barındırma ortamı vardır: ASP.Net (bunun ne olduğundan emin değilim) ve SQL Server. Kesin olarak söyleyebileceğim şey, SQL Server'ın tüm temelleri SOS (temelde bir kullanıcı işletim sistemi) olan, OS işletim sistemlerine asla dokunmadığı ve SOS temel öğelerinin kilit konvoylardan kaçınmak için tasarım gereği haksız olduğunu belirlemesidir (ör. FIFO garantisi verilmemiştir). Diğer yanıttaki bağlantı zaten işaret edildiği için, OS ilkelleri aynı zamanda kilit konvoylardan kaçınmak için aynı sebeple haksız davranışlar sağlamaya başladı. Kilit konvoyları hakkında daha fazla bilgi size Designing Applications for High Performance Rick Vicik makaleler okumalısınız için

:

Kilit Konvoy

FIFO kilitler adalet ve pahasına ileri ilerleme neden kilit konvoyları garanti . olarak rastgele kod boyunca dağıtılmış duruma göre daha yüksek bir çarpışma sonuçlanan bir grubu aynı kod kısmını gerçekleştirme terimi başlangıçta tasarlanan çeşitli konuları (çok gibi otomobil trafik ışıkları ile paketlerin gruplandırılır).Söz konusu olan fenomeni daha kötüdür, çünkü bir kez kilitli sahiplik kilitli mahsuplaşmayı oluşturduktan sonra kilitleme adımında iş parçacığı tutar.

Örnek vermek gerekirse, bir iş parçacığının bir kilidi tuttuğu ve kilidini tutarken önceliği olan örnek örneğini düşünün. Sonuç, diğer tüm yayınlar ürününün kilidi için bekleme listesine yığılmasıyla sonuçlanır. preempted iplik (şu anda sahibini kilitlemek) ve bültenleri tekrar kilidi çalıştırmak için aldığında, otomatik bekleme listedeki ilk Konuya kilidin sahipliğini eller. Bu iş parçacığı bir süre için çalışmayabilir, ancak "bekletme süresi" saat işaretleniyor. Önceki sahibi genellikle tekrar önce bekleme listesi konvoy

+0

doğru, statik bir nesnede statik bir nesne, ben çok hızlı yazdım. Şimdi tamir edecek – Matt

0

Windows hem CLR adalet bekleyen (FIFO sırası) garanti için ellerinden geleni girişiminde sürdürmekte, dışarı temizlenir kilit ister. Bununla birlikte, bir kilit üzerinde bekleyen ipliklerin sırasının değiştirilebildiği, çoğunlukla uyarılabilir beklemeler etrafında döndüğü ve tüm CLR iplik kilitlemesinin ipliğin uyarılabilir duruma getirildiği bazı senaryolar vardır.

Tüm pratik amaçlar için, siparişin FIFO olacağını varsayabilirsiniz; Ancak, bu sorunun farkında olun.

1

Basit bir örnek sırası ulaşmak kilidinin sürecini bakın ca gibi FIFO

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.Diagnostics; 


namespace ConsoleApplication 
{ 
    class Program 
    { 
     private static Info info = new Info(); 

     static void Main(string[] args) 
     { 
      Thread[] t1 = new Thread[5]; 
      for (int i = 0; i < 5; i++) 
      { 
       t1[i] = new Thread(info.DoWork); 
      } 

      Thread[] t2 = new Thread[5]; 
      for (int i = 0; i < 5; i++) 
      { 
       t2[i] = new Thread(info.Process); 
      } 

      for (int i = 0; i < 5; i++) 
      { 
       t1[i].Start(); 
       t2[i].Start(); 
      } 

      Console.ReadKey(); 
     } 
    } 

    class Info 
    { 
     public object SynObject = new object(); 

     public void DoWork() 
     { 
      Debug.Print("DoWork Lock Reached: {0}", Thread.CurrentThread.ManagedThreadId); 
      lock (this.SynObject) 
      { 
       Debug.Print("Thread Lock Enter: {0}", Thread.CurrentThread.ManagedThreadId); 
       Thread.Sleep(5000); 
       Debug.Print("Thread Lock Exit: {0}", Thread.CurrentThread.ManagedThreadId); 
      } 
     } 

     public void Process() 
     { 
      Debug.Print("Process Lock Reached: {0}", Thread.CurrentThread.ManagedThreadId); 
      lock (this.SynObject) 
      { 
       Debug.Print("Process Lock Enter: {0}", Thread.CurrentThread.ManagedThreadId); 
       Thread.Sleep(5000); 
       Debug.Print("Process Lock Exit: {0}", Thread.CurrentThread.ManagedThreadId); 
      } 
     } 
    } 
} 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.Diagnostics; 


namespace ConsoleApplication 
{ 
    class Program 
    { 
     private static Info info = new Info(); 

     static void Main(string[] args) 
     { 
      Thread[] t1 = new Thread[5]; 
      for (int i = 0; i < 5; i++) 
      { 
       t1[i] = new Thread(info.DoWork); 
      } 

      Thread[] t2 = new Thread[5]; 
      for (int i = 0; i < 5; i++) 
      { 
       t2[i] = new Thread(info.Process); 
      } 

      for (int i = 0; i < 5; i++) 
      { 
       t1[i].Start(); 
       t2[i].Start(); 
      } 

      Console.ReadKey(); 
     } 
    } 

    class Info 
    { 
     public object SynObject = new object(); 

     public void DoWork() 
     { 
      Debug.Print("DoWork Lock Reached: {0}", Thread.CurrentThread.ManagedThreadId); 
      lock (this.SynObject) 
      { 
       Debug.Print("Thread Lock Enter: {0}", Thread.CurrentThread.ManagedThreadId); 
       Thread.Sleep(5000); 
       Debug.Print("Thread Lock Exit: {0}", Thread.CurrentThread.ManagedThreadId); 
      } 
     } 

     public void Process() 
     { 
      Debug.Print("Process Lock Reached: {0}", Thread.CurrentThread.ManagedThreadId); 
      lock (this.SynObject) 
      { 
       Debug.Print("Process Lock Enter: {0}", Thread.CurrentThread.ManagedThreadId); 
       Thread.Sleep(5000); 
       Debug.Print("Process Lock Exit: {0}", Thread.CurrentThread.ManagedThreadId); 
      } 
     } 
    } 
} 

Yürütme bu

Process Lock Reached: 15 
Process Lock Enter: 15 
DoWork Lock Reached: 12 
Process Lock Reached: 17 
DoWork Lock Reached: 11 
DoWork Lock Reached: 10 
DoWork Lock Reached: 13 
DoWork Lock Reached: 9 
Process Lock Reached: 18 
Process Lock Reached: 14 
Process Lock Reached: 16 
Process Lock Exit: 15 
Thread Lock Enter: 9 
Thread Lock Exit: 9 
Process Lock Enter: 14 
Process Lock Exit: 14 
Thread Lock Enter: 10 
Thread Lock Exit: 10 
Thread Lock Enter: 11 
Thread Lock Exit: 11 
Process Lock Enter: 16 
Process Lock Exit: 16 
Thread Lock Enter: 12 
Thread Lock Exit: 12 
Process Lock Enter: 17 
Process Lock Exit: 17 
Thread Lock Enter: 13 
Thread Lock Exit: 13 
Process Lock Enter: 18 
Process Lock Exit: 18 

gibi bir şey procede olacak olması garanti olmadığını söyler kilit o farklıdır girmek.

İlgili konular