Örneklerle Ref, Var, Agent, Atom arasındaki Clojure farklılıkları


110

Clojure'da çok yeniyim, beyler bana gerçek dünya senaryoları ile açıklama yapabilir misiniz? Demek istediğim, Ref, Var, Agent, Atom nerede kullanılır. Kitap okudum ama yine de gerçek dünya örneklerini anlayamadım.

Yanıtlar:


174

Bu soruya gerçek bir yanıt için "Clojure Sevinci" veya "Clojure programlama" yı şiddetle tavsiye ederim, her biri için motivasyonların kısa bir parçasını yeniden oluşturabilirim:

Kimlik kavramı üzerine bu videoyu izleyerek ve / veya burada çalışarak başlayın .

  • Referanslar "Birçok Kimliğe" Eşgüdümlü Eşzamanlı erişim içindir.
  • Atomlar, tek bir Kimliğe Eşgüdümlü Eşzamanlı Erişim içindir.
  • Aracılar, tek bir Kimliğe Eşgüdümlü eşzamansız erişim içindir.
  • Vars, paylaşılan bir varsayılan değere sahip iş parçacığı yerel izole kimlikler içindir.

Koordineli erişim, iki Kimliğin birlikte değişmesi gerektiğinde kullanılır, klasik örnek parayı bir banka hesabından diğerine taşımaktır, ya tamamen hareket etmesi ya da hiç taşınmaması gerekir.

Koordinasyonsuz erişim, yalnızca bir Kimliğin güncellenmesi gerektiğinde kullanılır, bu çok yaygın bir durumdur.

Senkronize erişim, aramanın devam etmeden önce tüm Kimlikler yerleşene kadar beklemesi beklendiğinde kullanılır.

Eşzamansız erişim "ateşle ve unut" ve Kimliğin kendi zamanında yeni durumuna ulaşmasına izin ver.


Koordineli erişimde, yalnızca değiştirmek istiyorsam state-a, ancak state-bbunu yaparken başvuruda bulunuyorsam, yine de bir refdoğruya ihtiyacım var mı? Yani birden fazla şeyi değiştirmiyor, ancak herhangi birini değiştirirken birden çok şeye atıfta bulunuyor?
event_jr

2
Evet, durum-a ve durum-b'nin her ikisinin de refs olması gerektiğini doğru bir şekilde anlıyorsunuz. Durum-a'daki yeni değerin, a ve b'deki değerlerin tutarlı bir kombinasyonuna dayanmasını istiyorsanız. Bu yeni değerin, durum-a ve durum-b'nin birbiriyle tutarlı olduğu bir bağlamda hesaplanmış olması gerekir. Her ikisi de referans olduğunda, eğer b ortada değişirse, işlem yeniden başlayacak ve hem a hem de b'nin yeni değerlerini kullanacaktır. Bunu açık ve daha verimli hale getirmek için clojure.github.io/clojure/clojure.core-api.html#clojure.core/…ensure işlevini kullanmayı düşünün .
Arthur Ulfeldt

3
Cevabı tamamlamak için, Yalıtılmış paylaşılan varsayılan araçların ne olduğuna dair bir açıklama eklenebilir mi?
Didier A.

1
"Koordineli erişim, iki Kimliğin birlikte değiştirilmesi gerektiğinde kullanılır ...". Bu "değiştirilmeli" mi?
Carcigenicate

40

Referanslar, evreler arasında senkronize edilmesi gereken durumlar içindir. Bir dizi farklı şeyi takip etmeniz gerekiyorsa ve bazen birkaç şeyi aynı anda yazan işlemler yapmanız gerekirse, refs kullanın. Birden fazla farklı durumunuz olduğunda, ref kullanmak kötü bir fikir değildir.

Atomlar, iş parçacıkları arasında senkronize edilmesi gereken bağımsız durum içindir. Atomun ve başka herhangi bir şeyin durumunu hiçbir zaman değiştirmeniz gerekmeyecekse, atomda kullanmak güvenlidir (özellikle, tüm programda yalnızca tek bir durum parçası varsa, onu bir atoma koyabilirsiniz) . Önemsiz olmayan bir örnek olarak, bir işlevin dönüş değerlerini önbelleğe almaya çalışıyorsanız (yani, onu ezberlemek), bir atom kullanmak muhtemelen güvenlidir - durum, işlevin dışındaki her şey için görünmezdir, bu nedenle endişelenmenize gerek yoktur işlevin içindeki bir durumu bozan bir durum değişikliği hakkında.

Aracıların birincil noktası, farklı bir iş parçacığında çalışmasıdır. Aracının değerini alabilir ve ona bir işlevi değerine uygulamasını söyleyebilirsiniz, ancak işlevin ne zaman çalışacağını veya işlevin hangi değere uygulanacağını bilemezsiniz.

Vars, iş parçacığı başına bir şey kaydetmeniz gerektiğinde kullanılır. Çok iş parçacıklı bir programınız varsa ve her iş parçacığının kendi özel durumuna ihtiyacı varsa, bu durumu bir var.

Gerçek dünya örneklerine gelince, ne yapmaya çalıştığınıza dair bir örnek verirseniz, size ne kullanacağınızı söyleyebiliriz.


32

Bu türler hakkında ilk okuduğumda, her birini nerede kullanabileceğimi veya kullanmam gerektiğini anlamakta da zorlandım, bu yüzden işte benim basit İngilizce cevabım:

Veriler değişmediğinde bir var kullanın. Eğer her kullandığınızda bu gerçekleşir defile başlamak en fonksiyonları ya da defbenzeri defn.

Değişen tek bir öğeniz olduğunda bir atom kullanın. Bir örnek, öğe eklemek istediğiniz bir sayaç veya vektör olabilir.

Aynı anda değişmesi gereken iki veya daha fazla şeye sahip olduğunuzda bir ref kullanın. Aşina iseniz "veritabanı işlemlerini" düşünün. Bunun kanonik örneği, bir hesaptan diğerine para transferidir. Her hesap, atomik görünecek şekilde değişiklikler yapılabilmesi için bir ref içinde saklanabilir.

Bir şeyin değişmesini istediğinizde ancak ne zaman olacağı umurunuzda olmadığında bir temsilci kullanın. Bu uzun bir hesaplama veya bir dosyaya veya sokete bir şeyler yazmak olabilir. İkincisi ile kullanmanız gerektiğini unutmayın send-off.

Not: Bunların her biri için çok daha fazlası olduğunu takdir ediyorum, ancak umarım bu size bir başlangıç ​​noktası verir.


1
Net yanıtınız için çok teşekkürler :-) Benim gibi bir Clojure acemisine çok yardımcı oluyor.
gosukiwi

27

Aralarındaki farkı özetleyen bir makale yazdım ve hangisini kullanacağımı seçmeme yardımcı oldum.

Durumu paylaş - değişkenler, atomlar, aracılar ve referanslar kullanıldığında?

Umarım insanlara bu konuda cevaplar aramaya yardımcı olur.

@Tunaci önerisinden sonra makaleden bazı kısayollar:

Vars

Vars, her konu için globaldir.

Oluşturduktan sonra değişkenleri değiştirmeyin. Teknik olarak mümkün, ancak birçok nedenden dolayı kötü bir fikir.

Atomlar

Her iş parçacığı için değiştirilebilir duruma erişim paylaşın. Değişim eşzamanlı olarak gerçekleşir. Diğer iş parçacığı çalışma sırasında durumu değiştirdiğinde yeniden deneyin.

Uzun süreli yürütme ile idempotent işlevlerini ve işlevlerini kullanmayın

Ajanlar

Her iş parçacığı için değiştirilebilir duruma erişim paylaşın. Değişim eşzamansız olarak gerçekleşir.

refs

Refs, veritabanı işlemlerine benzer şekilde çalışır. Yazma ve okuma dosync'de korunur. İşlem sırasında birçok refs kasası üzerinde işlem yapabilirsiniz.

Ve hangisini kullanırken akış şeması: akış şemasıdır

Lütfen web sitesindeki resme bakın, çünkü bazı güncellemeler her zaman mümkündür.

Makaleyi kopyalamadan tam cevap vermek karmaşık ve uzun bir konudur, bu yüzden lütfen beni affet, seni web sitesine yönlendiriyorum :)


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.