Tam olarak da bir işlev nedir? | Netgez.com
SORU
9 Mayıs 2010, Pazar


Tam olarak da bir iÅŸlev nedir?

27* of the times*, reentrance tanımı Wikipedia: tırnak içine alınmış

Bir bilgisayar programı ya da rutin. eğer varsa evresel olarak nitelendirdi güvenli bir şekildedaha önce adı önceki çağırma tamamlandı (ben.e güvenle çalıştırılabilir aynı anda). Evresel olmak, bilgisayar programı veya rutin:

  1. Hayır statik (veya global)tutmak gerekir sabit olmayan veri.
  2. Adres dönmek zorunda değil statik (veya global) sabit olmayan veri.
  3. Sadece sağlanan verileri üzerinde çalışmak gerekir bunun için arayan tarafından.
  4. Singleton için kilitler güvenmek zorunda değil kaynaklar.
  5. Kendi kodunu değiştirmek gerekir. (tabii kendi yürütme benzersiz iplik depolama)
  6. Olmayan desteklemeyeceğini bilgisayar çağırmalısınız. Programlar veya rutinler.

Nasılgüvenli bir şekildetanımlanmış?

Eğer bir program olabilirgüvenli bir şekilde eş zamanlı olarak yürütüldüevresel?, her zaman mı bu yani

Tam altı puan desteklemeyeceğini yetenekleri için benim kodu kontrol ederken akılda tutulması gerektiğini belirtti arasındaki ortak konu nedir?

Ayrıca,

  1. Tüm özyinelemeli fonksiyonlar desteklemeyeceğini?
  2. Thread-safe fonksiyonları tüm desteklemeyeceğini?
  3. Özyinelemeli ve güvenli iplik-tüm fonksiyonları desteklemeyeceğini?

Bu soruyu yazarken, bir şey akla geliyor: Şartları gibidirreentranceveiş parçacığı güvenliğimutlak yani tüm sabit beton tanımları var mı? Eğer onlar değilse, bu soru çok anlamlı değil.

CEVAP
9 Mayıs 2010, Pazar


1. Nasıl . ben^>güvenli bir şekildetanımlanmış?

Anlamsal. Bu durumda, bu sabit tanımlı bir terim değildir. Sadece demek "bunu yapabilirsin, riski olmadan".

2. Eğer bir program güvenli bir şekilde aynı anda çalıştırılabilir, her zaman da öyle olduğu anlamına mı geliyor?

Hayır.

Örneğin, diyelim ki bir iki kilit ve bir parametre olarak geri götüren bir C işlevi vardır:

typedef void (*MyCallback)() ;
NonRecursiveMutex mutex ;

void myFunction(MyCallback f)
{
   lock(mutex) ;
   f() ;
   unlock(mutex) ;
}

İlk bakışta, bu işlev, Tamam... Ama bekle görünüyor:

int main(int argc, char * argv[])
{
   myFunction(myFunction) ;
   return 0 ;
}

Eğer dışlama kilit özyinelemeli değil, o zaman burada ne olacak:

  1. main myFunction arayacak
  2. myFunction kilidi almak olacaktır
  3. myFunction myFunction arayacak
  4. 2 myFunction kilidi almak, başarısız ve çıkacak bekleyin çalışacağız
  5. Kilitlenme.
  6. Oops...

Tamam, Geri arama olayı kullanarak hile yaptım. Ama kolay bir kod daha karmaşık parçaları benzer bir etkiye sahip düşünün.

3. Tam altı puan desteklemeyeceğini yetenekleri için benim kodu kontrol ederken akılda tutulması gerektiğini belirtti arasındaki ortak konu nedir?

Yapabilirsiniz . ben^>kokusueğer işlev/değiştirilebilir kalıcı bir kaynağa erişim izni verir veya/varsa bir sorun, bir işlev için erişim sağlar . ben^>kokuyor.

( . ben^>Tamam, 99% bizim kod koku, o zaman... son bölüm, o işlemek için)

Yani, kodunuzu okuyan, bu noktalardan biri sizi uyarmak gerekir:

  1. İşlevi bir devlet (erişim global bir değişken veya sınıf üye değişkeni bile yani)
  2. Bu işlev, birden çok iş parçacığı tarafından çağrılabilir veya iki kez bu işlemi yürütülürken yığın (kendisi, doğrudan veya dolaylı olarak arayabilir işlevi yani) görünebilir. Fonksiyonu parametre olarak geri alıyor . ben^>kokusubir sürü.

Non-yeniden kullanılabilirlik viral not : olası bir ara Bir işlevi olmayan desteklemeyeceğini işleyemez desteklemeyeceğini düşünülebilir.

C yöntemleri olduğunu da unutmayın . ben^>kokusukodu hiç komik etkileşimi olduğundan emin olmak için çalışması gerekir 14**, erişim var çünkü.

4.1. Tüm özyinelemeli fonksiyonlar desteklemeyeceğini?

Hayır.

Birden çok iş parçacığı durumlarda, özyinelemeli bir işlev paylaşılan bir kaynağa erişimini aynı anda birden çok iş parçacığı tarafından, kötü/bozuk veri ile sonuçlanan denilebilir.

Tek-iş parçacığına sahip durumda özyinelemeli bir işlevi olmayan da bir fonksiyon (gibi rezil strtok) kullanın veya verileri zaten kullanılıyor aslında küresel veri işleme olmadan kullanabilirsiniz. Sen çalışabilmesi kendisini doğrudan veya dolaylı olarak çağırır çünkü özyinelemeli, ama yine de olabilir . ben^>özyinelemeli-güvensiz.

4.2. Thread-safe fonksiyonları tüm desteklemeyeceğini?

Yukarıdaki örnekte, görünüşe göre iş parçacığı için güvenli bir işlev evresel değildir nasıl gösterdim. Tamam Geri arama parametresi yüzünden aldattım. Ama sonra, iki kez non-reccursive bir kilit almak suretiyle bir iş parçacığı kilitlenme için birden çok yolu vardır.

4.3. Özyinelemeli ve güvenli iplik-tüm fonksiyonları desteklemeyeceğini?

Derdim "" "" ne demek "özyinelemeli güvenli". özyinelemeli olursa Evet

Eğer bir fonksiyonu aynı anda birden çok iş parçacığı tarafından çağrılabilir, ve kendisi arayabilir, doğrudan veya dolaylı olarak, bir sorun olmadan garanti ederseniz, o zaman desteklemeyeceğini.

Sorun Bu garanti..< ^ _ deÄŸerlendirmektedir

5. Reentrance ve iplik güvenlik yani mutlak gibi terimler sabit beton tanımları var mı?

Onlar inanıyorum, ama sonra, bir işlev evresel veya desteklemeyeceğini olduğunu değerlendirmek zor olabilir. Bu terim kullanılır nedeni budur . ben^>kokusubir işlev evresel değildir bulabilirsiniz, ama kod karmaşık bir parça desteklemeyeceğini olduğundan emin olmak zor olabilir . yukarıda:

6. Bir örnek

Hadi bir nesne, bir kaynak kullanması gereken bir yöntem olduğunu varsayalım:

struct MyStruct
{
   P * p ;

   void foo()
   {
      if(this->p == NULL)
      {
         this->p = new P() ;
      }

      // Lots of code, some using this->p

      if(this->p != NULL)
      {
         delete this->p ;
         this->p = NULL ;
      }
   }
} ;

İlk sorun olduğunu Eğer bir şekilde bu işlevi çağrılır özyinelemeli olarak (yani bu işlev çağrıları kendisi, doğrudan veya dolaylı olarak), kod muhtemelen kaza, çünkü this->p silinecek sonunda son çağrı, ve hala muhtemelen kullanılan sona ermeden önce arayın.

Böylece, bu kod değil . ben^>özyinelemeli-güvenli.

Bir başvuru bu doğru karşı kullanabiliriz:

struct MyStruct
{
   size_t  c ;
   P *     p ;

   void foo()
   {
      if(c == 0)
      {
         this->p = new P() ;
      }

        c ;

      // Lots of code, some using this->p

      --c ;

      if(c == 0)
      {
         delete this->p ;
         this->p = NULL ;
      }
   }
} ;

Bu sayede, kodu olur, özyinelemeli-güvenli... Ama hala çalışmıyor desteklemeyeceğini nedeniyle çoklu sorunları: Biz olmalı tabii değişiklikler c p yapılacak atomik kullanarak birözyinelemelizaman uyumu (tüm uyumu tekrar eder):

struct MyStruct
{
   mutex   m ; // recursive mutex
   size_t  c ;
   P *     p ;

   void foo()
   {
      lock(m) ;
      if(c == 0)
      {
         this->p = new P() ;
      }

        c ;
      unlock(m) ;

      // Lots of code, some using this->p

      lock(m) ;
      --c ;

      if(c == 0)
      {
         delete this->p ;
         this->p = NULL ;
      }
      unlock(m) ;
   }
} ;

Ve tabii ki, bu lots of code kendisini desteklemeyeceğini, p kullanımı da dahil olmak üzere varsayar.

Ve yukarıdaki kod bile uzaktan exception-safe ama bu..< ^ _ başka bir hikaye değil

7. Kodumuzun ™'u desteklemeyeceÄŸini deÄŸil!

Spagetti kod için oldukça doğrudur. Ama eğer doğru kodu bölüm varsa, yeniden kullanılabilirlik sorunları önlemek olacaktır.

7.1. Tüm fonksiyonları HİÇBİR devlet olduğundan emin olun.

Sadece devlet olmadan parametreleri, kendi yerel değişkenler, diğer fonksiyonları kullanın, ve eğer geri gelirse verilerin kopyalarını geri dönmek zorundalar.

7.2. Nesne olduğundan emin olun "özyinelemeli güvenli".

Nesne yöntemi nesnenin aynı örneği tüm yöntemleri ile devlet hisselerinin 24**, erişimi vardır.

Yani, emin olun nesneyi kullanılabilir bir noktada yığın (yani arama yöntemi), ve daha sonra, başka bir noktaya (yani arama yöntemi B), ayartıcı olmadan bütün nesne. Nesne bir yöntem çıkarken, nesne ve (sarkan işaretçiler, hiçbir aykırı üye değişkenleri, vb.) istikrarlı doğru olduğundan emin olmak için tasarım.

7.3. Tüm nesneleri düzgün kapsüllü olduğundan emin olun.

Hiç kimse kendi iç veri erişimi olmalıdır:

   // bad
   int & MyObject::getCounter()
   {
      return this->counter ;
   }

   // good
   int MyObject::getCounter()
   {
      return this->counter ;
   }

   // good, too
   void MyObject::getCounter(int & p_counter)
   {
      p_counter = this->counter ;
   }

Hatta sabit bir referans iade eder kodun bir kısmı diğer kısmını kod tutmadan değişiklik mi olarak veri adresini alır, tehlikeli olabilir inş başvurusu söylenmişti.

7.4. Kullanıcı iş parçacığı için güvenli değil diye itiraz bildiğinden emin olun

Böylece, kullanıcı uyumu bir nesnenin iş parçacığı arasında paylaşılan kullanmak için sorumludur.

Nesneleri STL tasarlanmıştır için iş parçacığı güvenli (çünkü performans sorunları), ve böylece, eğer bir kullanıcı paylaşalım std::string arasında iki iş parçacığı, kullanıcı korumak gerekir erişimi olan eşzamanlılık temel öğeler;

7.5. Emin kod özyinelemeli-güvenli iş parçacığı için güvenli olun

Bu aynı kaynak iki defa aynı iş parçacığı tarafından kullanılabilir düşünüyorsanız özyinelemeli uyumu kullanarak anlamına gelir.

Bunu PaylaÅŸ:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VÄ°DEO

Rastgele Yazarlar

  • disneychannel

    disneychanne

    19 ÅžUBAT 2006
  • glowpinkstah

    glowpinkstah

    16 Mayıs 2006
  • TheRightTire

    TheRightTire

    14 EKÄ°M 2009