2016-03-24 37 views
0

N Hz'de bir iş parçacığında paylaşılan belleğe veri yazan bir sensör var (saniyede 10Hz = 10 kez). Ayrı bir iş parçacığı bu verileri okuyor ve bazı sonuçları elde etmek için kullanıyor. Okuyucu parçanın frekansı farklıdır. Hesaplanana bağlı olarak, saniyede 8 kez veya saniyede 15 kez daha yavaş olabilir. Okuyucu iş parçacığı sadece paylaşılan bellekteki verileri okur. Verileri değiştirmez (yalnızca sonuç almak için işleyin) ve paylaşılan belleğe hiçbir şey yazmaz. Tüm süreç çok düzgün çalışıyor. Okuyucu, ihtiyaç duyulduğunda paylaşılmış hafızada ne olduğunu okunduğundan (veri için anket yapar) senkronizasyon umurumda değil. İki okuma arasında, paylaşılan belleğin içeriği değişirse, okuyucu yeni verileri kullanır. Eğer iki okuma arasında paylaşılan hafızanın içeriği değişmezse (okuyucu yazardan çok daha hızlıysa), okuyucu sadece paylaşılmış hafızada ne olursa olsun kullanır.Donanım uygulamaları için Paylaşılan Bellek (C++) kullanırken Mutex için İhtiyaç Var

Artık meslektaşım, bir muteks kullanarak paylaşılan belleğe erişimi eşitlemem gerektiğini söylüyor ancak katılmıyorum. Nedeni, erişimi kontrol etmek için bir muteks kullanırsam, yazarın paylaşımlı belleğe yazma sıklığı biraz azalır (okuyucu iş parçacığı muteks ve yazıyı kilitlediğinde). Gelecekte daha fazla okuyucuyu ele alacağız ve yazar dizisinin paylaşımlı belleğe yazabileceği sıklığın, muteks için rekabet eden iki konu daha olacağından, daha da azalacağından korkuyorum.

Yarış koşulları vb. Hakkında bilgi sahibiyim, fakat yarış koşullarını ve diğer sitelerde verilen sayısız örneklerin de benimkilerden farklı senaryoları düşündüğünü hissediyorum: İki iş parçacığı, banka dengesini okurken ve işlerken ve bir iş parçacığı daha yavaşsa veya okumada daha hızlı ve denge miktarı hatalı olarak sonuçlanıyor ... sonuçta 2000 $ yerine 2000 dolar. Ancak, benim durumumda, "banka bakiyesi" - paylaşılacak veriler bir sensör tarafından üretiliyor. Değerdeki herhangi bir değişiklik fiziksel nedenlerden kaynaklanır ve paylaşılacak veri değeri hiçbir zaman büyük miktarda atlamayacaktır.

Daha fazla bilgi: Sensör, bir mesafe ölçüm sensörüdür. Saniyede 10 kez mesafeyi ölçer. T = 1,0s olan mesafeyi 10 cm olarak söyleyin ve hafızaya yazılmıştır. Okuyucu 10cm yazan paylaşılan hafızayı okur. Okuyucunun verileri okurken veya işlerken gerçek mesafenin değişmesi durumunda, bu mesafe 10,1 cm olacak veya mesafe asla büyük miktarlarda atlamayacağı için. Bir sonraki ankette, okuyucu 10.1cm'lik mesafeyi okuyacaktır (nesnenin durağan olduğunu varsayarak). Bu şekilde, yazar dizim, bir muteksin kilitlenmesini beklemeden mümkün olduğunca hızlı yazabilir.

Gerekçelendirmem yanlış mı? Hayal edebileceğim tek sorun, yazarım ve okuyucu iş parçacıklarımın aynı anda belleğe erişmeye çalışmasıdır. Ama sonra, zamanlayıcı talimatlar arasında geçiş yapmak gerekiyor, değil mi? Yani, sadece sahte paralel işlem, doğru mu? Bu, her ikisinin de belleğe aynı anda erişemedikleri anlamına gelir, değil mi?

+1

Sorunuza TL; DR bölümü eklemek isteyebilirsiniz. –

+0

Sadece bir iş parçacığına sahip olduğunuz sürece güvende olduğunuzu düşünüyorum. – Marco

+0

Genel olarak, paylaşılan belleğin korunmasını kullanmalısınız (ör. Bir muteks). Ancak, belirli bir platform için kodlama yapıyorsanız ve taşınabilir kodlara gerek duymuyorsanız ve veri türleri basit (yerel) türlerse, mutex olmadan da yapabilirsiniz. Bu, sisteminizin düşük seviyeli bilgisine ihtiyaç duyacaktır. – 4386427

cevap

3

bu yanıtın bir açıklama olması gerekiyordu eğer öyleyse, lütfen bana bildirin, bilmiyorum ...

Bir dairesel tampon uygulamak deneyebilirsiniz. Bu şekilde, yazar sadece tampon ile döner ve yazmaya devam eden bir işaretçiye sahiptir. Okuyucu aynıdır, sadece yazarın 'arkasında' olmalıdır.

Bu, yazar birtakım değerler yazdığında, ne kadar verinin mevcut olduğunu belirten değişkeni arttırması gerektiği anlamına gelir. Okuyucu bir örnek okuduğunda, bu değişkeni azaltmalıdır. Bu operasyonların bir muteks içinde kilitlenmesi gerekiyor. I ++ ve i-- atomik işlemler olsa da, çok çekirdekli bir sistemde, bu hala sorun yaratabilir, bunu zor yoldan buldum.

Evet, mutekslere ihtiyacınız var, ancak sadece bir değişkende olması gerektiğinden, programınızın tamamını yavaşlatmaz ...

1

Önleyici görevler kullanıyorsanız, uygulamanıza bağlıdır (E.g Interrupts). Okuma ipliğinin değeri okuması ve okuma sırasında yazılan iplik tarafından kesilmesi mümkündür. Sizin durumunuzda değerin sadece bir tamsayı olduğunu varsayardım, o yüzden onun kırılgan değil. Sadece okuma ibresindeki her yürütme için verileri bir kez okuduğunuzdan emin olun (atomik işlemlere bakın). Değer bir kayıt değerinden daha büyükse. Kuyrukların ve çok düzeyli tamponların kullanımıyla bir muteksin önüne geçebilirsiniz. Ama bu hafıza kullanımınızı artırıyor. Durumunuzda: Verileriniz bir tam sayıdan büyükse tripple arabelleğe alınmış belleği kullanmanızı öneririm. Bu durumda üç arabelleğe sahip olursunuz, bu değer ilk olarak yazılır ve tamamlandıktan sonra, okuma ipliğinizin okunması mümkünken arabelleği bir ara ile değiştirilir.

1

Davanızdaki sorun, okuyucunun değişken yazıldığı anda okuyabiliyor olması, problemin sadece yazım şeklidir, bu yüzden bu yazma için atomik işlemleri kullanmanızı öneririm, böylece muteks'e ihtiyacınız olmaz. Veriler hizalanırsa okurlar atomiktir (bkz. Read and Write atomic operation implementation in the Linux Kernel), yazma işlemleri için emin değilim, ancak belki de yapamayacağımız şey şu şekilde olmaz:

C++, C++ İşlemlerin atomik olduğunu garanti edin: http://en.cppreference.com/w/c/atomic C, http://www.gnu.org/software/libc/manual/html_node/Atomic-Types.html standardında tanımlanan bu tür sig_atomic_t türlerini okuyup yazmanın atomik işlemlerini garantilemiş buldum, mutex olmadan hile yapmalı.

+0

Bu çok önemli ve yararlı bir şey. Teşekkürler. Sig_atomic_t türü benim için yeni ve çok kullanışlı görünüyor ama bu durumda bir çift kullanıyorum. Verileri yazmak için bir memcpy yapıyorum, böylece atomik yapmaya çalışacağım. Memcpy atomik yapmak için bir veya iki sayfa gördünüz. – user1420