2010-09-20 16 views
5

Ruby ile eşzamansız bir I/O kütüphanesi arasında bir arabirim sağlayarak bir C uzantısı yazdım. Benim kod üzerinde testler çalıştırırken, sık sık hatalar dahil (ancak bunlarla sınırlı olmamak üzere) olsun:Ruby uzantısında çapraz iş ihlallerini nasıl önleyebilirim?

[BUG] cross-thread violation in rb_thread_schedule() 

Asenkron IO benim C uzantısı birden çok iş parçacığı (değil ana tercüman parçacığı) den yakut için mesajlar vermek gerekecektir demektir . Süreçte bu iplik güvenliği ihlallerini nasıl önleyebilirim? Yakut için

+0

Ruby 1.8.x veya 1.9.x? – llasram

+0

Benim endişem 1.8 oldu, ama 1.9 de geçerlidir. –

cevap

7

belirgin olanıdır hatayı önlemenin tek yolu 1.8.x - sadece ana tercüman iplikten Yakut/C API çağırmak. Bunun da ruby ​​1.9.x için geçerli olduğuna inanıyorum, ama ben bununla çalışmadım ve yerel iş parçacığı desteğinin işleri nasıl değiştirdiğini bilmiyorum. Birden çok yerel iş parçacığı doğrudan API'yi çağırmak yerine, ikincil yerel ileti dizilerinden ana yorumlayıcı iş parçasındaki kodunuza istek göndermek için üretici/tüketici kalıbını kullanmanız gerekir. Ve ideal olarak diğer Ruby yeşil iş parçacığını gereksiz yere engellemeden yaparken bunu yapın. Ruby uygulamasına bakarsanız, yakut yeşil iş parçacığı zamanlayıcısı temel olarak bir select() döngüdür.

  • bir boru ya da gerçek select() sıfat daha dosya tanıtıcı sağlayan diğer IPC mekanizması oluşturun: Bu, aşağıdaki genel yapıyı göstermektedir.
  • yumurtası doğal lifler borunun yazma ucu ile sağlamak ve. Ana tercüman parçacığı olarak
  • , borunun okunan ucunda rb_thread_wait_fd() çağıran bir olay döngü girin. Bu yakut yeşil iş parçacığı zamanlayıcı diğer yeşil iş parçacığı çalıştırmak için izin verecektir. İkincil yerli ipler ana iş parçacığı için istekleri varsa
  • , bunları sıraya ve aynı zamanda olay döngü çalışan yeşil iplik uyanma, boruya yazma.

muhtemelen yakut kod tabanı basit temiz IO kullanan işlevi ne için rb_io_sysread() (IO#sysread uygulanmasını) bakınız.

İlgili konular