Yeniden giriş işlevi tam olarak nedir?


199

Çoğu ait zamanlarda , reentrance tanımı alıntı yapıldığı Vikipedi :

Bir bilgisayar programı veya rutini, önceki çağrısı tamamlanmadan önce güvenli bir şekilde yeniden çağrılabiliyorsa (yani eşzamanlı olarak güvenli bir şekilde çalıştırılabilir) evresel olarak tanımlanır . Tekrar girebilmek için bir bilgisayar programı veya rutini:

  1. Statik (veya global) sabit olmayan veri içermemelidir.
  2. Adresi statik (veya global) sabit olmayan verilere döndürmemelidir.
  3. Yalnızca arayan tarafından kendisine sağlanan veriler üzerinde çalışmalıdır.
  4. Singleton kaynaklarının kilitlerine güvenmemelidir.
  5. Kendi kodunu değiştirmemelidir (kendi benzersiz iş parçacığı deposunda yürütülmedikçe)
  6. Evresel olmayan bilgisayar programlarını veya rutinlerini çağırmamalıdır.

Güvenli bir şekilde nasıl tanımlanır?

Bir program eşzamanlı olarak güvenli bir şekilde yürütülebiliyorsa , her zaman yeniden girildiği anlamına mı gelir?

Kodumu yeniden giriş yetenekleri için kontrol ederken akılda tutmam gerektiğini belirtti altı nokta arasındaki ortak iş parçacığı tam olarak nedir?

Ayrıca,

  1. Tüm özyinelemeli fonksiyonlar yeniden girer mi?
  2. Tüm iş parçacığı için güvenli işlevler yeniden girildi mi?
  3. Tüm özyinelemeli ve iş parçacığı için güvenli işlevler yeniden gönderiliyor mu?

Bu soruyu yazarken akla gelen bir şey var: Yeniden girme ve iplik güvenliği gibi terimler mutlak mı yani sabit somut tanımları var mı? Çünkü eğer değillerse, bu soru çok anlamlı değildir.


6
Aslında ilk listede # 2 ile aynı fikirde değilim. Bir yeniden giriş işlevinden istediğiniz adrese bir adres döndürebilirsiniz - sınırlama, arama kodundaki bu adresle yaptıklarınızdadır.

2
@Neil Ama evresel fonksiyonun yazarı, arayan kişinin kesinlikle ne kontrol edemediğinden, gerçek bir şekilde evre olabilmesi için statik (veya küresel) sabit olmayan verilere bir adres döndürmemelidir?
Robben_Ford_Fan_boy

2
@drelihan Arayanın döndürülen bir değerle ne yaptığını kontrol etmek HERHANGİ bir fonksiyonun (tekrar girip girmeme) yazarının sorumluluğu değildir. Arayanın onunla ne yapabileceğini kesinlikle söylemeliler, ancak arayan başka bir şey yapmayı seçerse - arayana zor şans.

“thread-safe”, evrelerin ne yaptığını ve yaptıklarının beklenen etkisinin ne olduğunu belirtmedikçe anlamsızdır. Ama belki de bu ayrı bir soru olmalı.

Güvenle kastediyorum, zamanlama ne olursa olsun davranış iyi tanımlanmış ve belirleyicidir.
AturSams

Yanıtlar:


192

1. Nasıl güvenli bir şekilde tanımlanır?

Semantik. Bu durumda, bu tanımlanmış bir terim değildir. Bu sadece "Risksiz bunu yapabilirsin" demek.

2. Bir program aynı anda güvenli bir şekilde yürütülebiliyorsa, bu her zaman yeniden girildiği anlamına mı gelir?

Hayır.

Örneğin, hem kilit hem de geri çağrıyı parametre olarak alan bir C ++ işlevine sahip olalım:

#include <mutex>

typedef void (*callback)();
std::mutex m;

void foo(callback f)
{
    m.lock();
    // use the resource protected by the mutex

    if (f) {
        f();
    }

    // use the resource protected by the mutex
    m.unlock();
}

Başka bir fonksiyonun aynı muteksi kilitlemesi gerekebilir:

void bar()
{
    foo(nullptr);
}

İlk bakışta her şey yolunda görünüyor ... Ama bekleyin:

int main()
{
    foo(bar);
    return 0;
}

Muteks üzerindeki kilit özyinelemeli değilse, ana iş parçacığında neler olacak:

  1. mainarayacak foo.
  2. foo kilidi alacak.
  3. fooarayacak bar, arayacak foo.
  4. 2 foo, kilidi almak başarısız ve tahliye edilecek beklemek çalışacağız.
  5. Kilitlenme.
  6. Hata ...

Tamam, geri çağırmayı kullanarak hile yaptım. Ancak benzer bir etkiye sahip daha karmaşık kod parçalarını hayal etmek kolaydır.

3. Kodumu yeniden giriş yetenekleri için kontrol ederken akılda tutmam gereken altı nokta arasındaki ortak konu tam olarak nedir?

Sen edebilirsiniz kokusu sizin fonksiyon / değiştirilebilir bir kalıcı bir kaynağa erişim sağlar veya has / bir işleve erişim sağlar eğer bir sorun kokuyor .

( Tamam, kodumuzun% 99'u koklamalı, o zaman… Bunu yapmak için son bölüme bakın… )

Kodunuzu incelemek için, bu noktalardan biri sizi uyarmalıdır:

  1. Fonksiyonun bir durumu vardır (yani bir global değişkene, hatta bir sınıf üyesi değişkenine erişim)
  2. Bu işlev birden çok iş parçacığı tarafından çağrılabilir veya işlem yürütülürken yığında iki kez görünebilir (yani işlev kendisini doğrudan veya dolaylı olarak çağırabilir). Parametreler çok koktuğunda işlev geri çağrıları alır .

Tekrar girmeyenlerin viral olduğunu unutmayın: Olası yeniden girmeyen bir işlev çağırabilecek bir işlev, yeniden giriş olarak kabul edilemez.

Ayrıca, C ++ yöntemlerinin erişime sahip oldukları için koktuğunu unutmayın, bu thisnedenle komik bir etkileşime sahip olmadıklarından emin olmak için kodu incelemelisiniz.

4.1. Tüm özyinelemeli fonksiyonlar yeniden girer mi?

Hayır.

Çok iş parçacıklı durumlarda, aynı anda birden çok iş parçacığı tarafından paylaşılan bir kaynağa erişen özyinelemeli bir işlev çağrılabilir ve bu da verilerin bozuk / bozuk olmasına neden olabilir.

Tek kullanımlık durumlarda, özyinelemeli bir işlev, evresel olmayan bir işlev (rezil gibi strtok) kullanabilir veya verilerin zaten kullanımda olduğu gerçeğini ele almadan küresel verileri kullanabilir. Bu nedenle işleviniz özyinelemeli çünkü doğrudan veya dolaylı olarak kendini çağırıyor, ancak yine de özyinelemeli-güvensiz olabilir .

4.2. Tüm iş parçacığı için güvenli işlevler yeniden girildi mi?

Yukarıdaki örnekte, görünüşe göre threadsafe fonksiyonunun nasıl yeniden girilmediğini gösterdim. Tamam, geri arama parametresi nedeniyle hile yaptım. Ancak, iki kez özyinelemeyen bir kilit elde etmesini sağlayarak bir iş parçacığını kilitlemenin birçok yolu vardır.

4.3. Tüm özyinelemeli ve iş parçacığı için güvenli işlevler yeniden gönderiliyor mu?

Eğer "özyinelemeli" ile "özyinelemeli-güvenli" demek istiyorsanız "evet" derdim.

Bir işlevin aynı anda birden çok iş parçacığı tarafından çağrılabileceğini ve kendisini doğrudan veya dolaylı olarak sorunsuz bir şekilde çağırabileceğini garanti ediyorsanız, o zaman yeniden girilir.

Sorun bu garantiyi değerlendiriyor… ^ _ ^

5. Tekrarlama ve iplik güvenliği gibi terimler mutlak midir, yani sabit somut tanımları var mı?

Yaptıklarına inanıyorum, ancak daha sonra bir işlevi değerlendirmek iş parçacığı açısından güvenli veya yeniden girme zor olabilir. Bu yüzden yukarıdaki koku terimini kullandım : Bir fonksiyonun reentrant olmadığını, ancak karmaşık bir kod parçasının reentrant olduğundan emin olmak zor olabilir

6. Bir örnek

Bir kaynağı kullanmanız gereken bir yöntemle bir nesneniz olduğunu varsayalım:

struct MyStruct
{
    P * p;

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

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

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

İlk sorun, bu işlev bir şekilde özyinelemeli olarak adlandırılırsa (yani, bu işlev doğrudan veya dolaylı olarak çağrılırsa), kodun büyük olasılıkla çökmesine neden olur, çünkü this->pson çağrının sonunda silinir ve yine de muhtemelen sonundan önce kullanılır İlk aramanın

Bu nedenle, bu kod özyinelemeli-güvenli değildir .

Bunu düzeltmek için bir referans sayacı 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 = nullptr;
        }
    }
};

Bu şekilde, kod özyinelemeli güvenli olur ... Ama yine de, çünkü sorunlar çoklu kullanım evresel değildir: Biz olmalı emin modifikasyonları cve pbir kullanarak, atomik olarak yapılacaktır özyinelemeli Muteksleri (tüm muteksler özyinelemelidir):

#include <mutex>

struct MyStruct
{
    std::recursive_mutex m;
    size_t c;
    P * p;

    void foo()
    {
        m.lock();

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

        ++c;
        m.unlock();
        // lots of code, some using this->p
        m.lock();
        --c;

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

        m.unlock();
    }
};

Ve elbette, bu lots of code, kullanımı da dahil olmak üzere kendisinin reentrant olduğunu varsayar p.

Ve yukarıdaki kod uzaktan bile istisna-güvenli değil , ama bu başka bir hikaye… ^ _ ^

7. Hey kodumuzun% 99'u evresel değildir!

Spagetti kodu için oldukça doğrudur. Ancak kodunuzu doğru şekilde bölümlere ayırırsanız, yeniden giriş sorunlarından kaçınacaksınız.

7.1. Tüm işlevlerin HAYIR durumu olmadığından emin olun

Sadece parametreleri, kendi yerel değişkenlerini, durum bilgisi olmayan diğer işlevleri kullanmalı ve geri döndüklerinde verilerin kopyalarını döndürmelidirler.

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

Bir nesne yönteminin erişimi vardır this, bu nedenle bir nesneyi nesnenin aynı örneğinin tüm yöntemleriyle paylaşır.

Bu nedenle, nesnenin tüm nesneyi bozmadan yığındaki bir noktada (yani yöntem A'yı çağırmak) ve sonra başka bir noktada (yani yöntem B'yi çağırmak) kullanılabildiğinden emin olun. Nesnenizi bir yöntemden çıktıktan sonra nesnenin sabit ve doğru olduğundan emin olmak için tasarlayın (sarkan işaretçiler, çelişen üye değişkenler vb. Yok).

7.3. Tüm nesnelerinizin doğru şekilde kapsüllendiğinden emin olun

Başka hiç kimse dahili verilerine erişemez:

    // 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;
    }

Kodun başka bir kısmı, sabit referansı tutan kod söylenmeden değiştirilebileceğinden, kullanıcı verilerinin adresini alırsa bir const referansı döndürmek bile tehlikeli olabilir.

7.4. Kullanıcının nesnenizin iş parçacığı için güvenli olmadığını bildiğinden emin olun

Bu nedenle, kullanıcı iş parçacıkları arasında paylaşılan bir nesneyi kullanmak için muteksleri kullanmaktan sorumludur.

STL'den gelen nesneler, iş parçacığı açısından güvenli olmayacak şekilde tasarlanmıştır (performans sorunları nedeniyle) ve bu nedenle, kullanıcı std::stringiki iş parçacığı arasında bir paylaşım yapmak istiyorsa , kullanıcının erişimini eşzamanlılık ilkelleriyle koruması gerekir;

7.5. İş parçacığı güvenli kodunuzun yinelemeli olarak güvenli olduğundan emin olun

Bu, aynı kaynağın aynı iş parçacığı tarafından iki kez kullanılabileceğine inanıyorsanız, özyinelemeli mutekslerin kullanılması anlamına gelir.


1
Biraz tartışmak için, aslında bu durumda "güvenlik" tanımlı olduğunu düşünüyorum - bu işlev sadece sağlanan değişkenler üzerinde hareket edecek anlamına gelir - yani, altındaki tanım teklifi için kısayol. Ve nokta, bunun diğer güvenlik fikirleri anlamına gelmeyebileceği.
Joe Soul-getirici

İlk örnekte muteksi geçmeyi özlediniz mi?
detly

@paercebal: örneğiniz yanlış. Aslında geri arama ile uğraşmanıza gerek yok, eğer varsa basit bir özyineleme aynı soruna sahip olacaktır, ancak tek sorun tam olarak kilidin nerede tahsis edildiğini söylemeyi unutmanızdır.
Yttrill

3
@Yttrill: İlk örnek hakkında konuştuğunuzu varsayıyorum. "Geri aramayı" kullandım çünkü özünde bir geri arama kokuyor. Tabii ki, özyinelemeli bir işlev aynı soruna sahip olacaktır, ancak genellikle bir işlev ve özyinelemeli doğasını kolayca analiz edebilir, böylece, yeniden evreli olup olmadığını veya özyinelemeye uygun olup olmadığını tespit edebilir. Diğer yandan geri arama, geri aramayı çağıran fonksiyonun yazarının geri arama ne yaptığı hakkında hiçbir bilgiye sahip olmadığı anlamına gelir, bu nedenle bu yazar işlevinin yeniden girildiğinden emin olmakta zorlanabilir. Göstermek istediğim bu zorluk bu.
paercebal

1
@Gab 是 好人: İlk örneği düzelttim. Teşekkürler! Bir sinyal işleyici, genellikle bir sinyal yükseltildiğinde, özel olarak bildirilmiş bir küresel değişkeni değiştirmenin ötesinde hiçbir şey yapamazsınız.
paercebal

21

"Güvenle" tam olarak sağduyunun belirlediği şekilde tanımlanır - "başka şeylere müdahale etmeden işini doğru yapmak" anlamına gelir. Alıntı yaptığınız altı nokta bunu başarmak için gereken şartları açıkça ifade eder.

3 sorularınızın cevapları 3 × "hayır" dır.


Tüm özyinelemeli fonksiyonlar yeniden girer mi?

HAYIR!

Örneğin, aynı global / statik verilere erişmeleri durumunda, özyinelemeli bir işlevin iki eşzamanlı çağrısı birbirlerini kolayca vidalayabilir.


Tüm iş parçacığı için güvenli işlevler yeniden girildi mi?

HAYIR!

Bir işlev eşzamanlı olarak çağrılırsa arızalanmıyorsa iş parçacığı açısından güvenlidir. Ancak bu, örneğin birinci çağrının bitimine kadar ikinci çağrının yürütülmesini engellemek için bir muteks kullanılarak gerçekleştirilebilir, böylece bir seferde yalnızca bir çağırma çalışır. Tekrar giriş , diğer çağrılara müdahale etmeden eş zamanlı olarak yürütmek anlamına gelir .


Tüm özyinelemeli ve iş parçacığı için güvenli işlevler yeniden gönderiliyor mu?

HAYIR!

Yukarıyı görmek.


10

Ortak konu:

Rutin kesintiye uğrarken çağrılırsa davranış iyi tanımlanmış mı?

Eğer böyle bir fonksiyonunuz varsa:

int add( int a , int b ) {
  return a + b;
}

O zaman herhangi bir dış duruma bağımlı değildir. Davranış iyi tanımlanmıştır.

Eğer böyle bir fonksiyonunuz varsa:

int add_to_global( int a ) {
  return gValue += a;
}

Sonuç, birden çok iş parçacığında iyi tanımlanmamıştır. Zamanlama yanlışsa bilgi kaybedilebilir.

Bir yeniden giriş işlevinin en basit şekli, yalnızca iletilen argümanlar ve sabit değerler üzerinde çalışan bir şeydir. Başka herhangi bir şey özel bir işlem gerektiriyor veya çoğu zaman yeniden girmiyor. Ve elbette, argümanlar değişebilen küresellere atıfta bulunmamalıdır.


7

Şimdi önceki yorumum üzerinde durmak zorundayım. @paercebal yanıtı yanlış. Örnek kodda kimse parametre olması gereken muteksin gerçekte aktarılmadığını fark etmedi mi?

Sonucu itiraz ediyorum, iddia ediyorum: bir fonksiyonun eşzamanlılık durumunda güvenli olması için yeniden girilmesi gerekir. Bu nedenle, eşzamanlı-güvenli (genellikle iş parçacığı-güvenli olarak yazılır) yeniden giriş anlamına gelir.

Ne iş parçacığı için güvenli ne de yeniden giriş yapanların argümanlar hakkında söyleyecek bir şeyleri yoktur: işlevin eşzamanlı yürütülmesi hakkında konuşuyoruz, uygunsuz parametreler kullanılırsa yine de güvenli olmayabilir.

Örneğin, memcpy () iş parçacığı için güvenli ve yeniden girilir (genellikle). Açıkçası, iki farklı evreden aynı hedeflere işaretçilerle çağrıldığında beklendiği gibi çalışmaz. SGI tanımının amacı budur ve aynı veri yapısına erişimin istemci tarafından senkronize edilmesini sağlamak için istemciye yerleştirme.

Genel olarak saçmalık olduğunu anlamak önemlidirİplik güvenli çalışmanın parametreleri dahil etmesinin . Herhangi bir veritabanı programlama yaptıysanız anlayacaksınız. "Atomik" olan ve bir muteks veya başka bir teknikle korunabilecek kavramın mutlaka bir kullanıcı kavramı olması gerekir: bir veritabanında bir işlemin işlenmesi birden fazla kesintisiz değişiklik gerektirebilir. Müşteri programcısı dışında hangilerinin senkronize tutulması gerektiğini kim söyleyebilir?

Mesele şu ki, "yolsuzluk" un bilgisayarınızdaki yazılmamış belleklerle karıştırılması gerekmemektedir: tüm bireysel işlemler serileştirilmiş olsa bile yolsuzluk yine de meydana gelebilir. Bir işlevin iş parçacığı açısından güvenli mi yoksa yeniden girip girmediğini sorduğunuzda, soru, uygun şekilde ayrılmış tüm bağımsız değişkenler için anlamına gelir: birleştirilmiş bağımsız değişkenlerin kullanılması bir karşı örnek oluşturmaz.

Orada birçok programlama sistemleri var: Ocaml bir, ve bence Python, içlerinde çok fazla evresel olmayan kod var, ancak iş parçacığı girişlerini serpiştirmek için küresel bir kilit kullanıyor. Bu sistemler yeniden giriş yapmazlar ve iş parçacığı veya eşzamanlı olarak güvenli değildirler, küresel olarak eşzamanlılığı önledikleri için güvenli bir şekilde çalışırlar.

Buna iyi bir örnek malloc. Tekrar girilmez ve iş parçacığı için güvenli değildir. Bunun nedeni, genel bir kaynağa (yığın) erişmesi gerektiğidir. Kilitleri kullanmak güvenli hale getirmez: kesinlikle yeniden giriş yapmaz. Malloc ile arayüz düzgün bir şekilde tasarlanmış olsaydı, yeniden giriş ve iş parçacığı için güvenli hale getirmek mümkün olurdu:

malloc(heap*, size_t);

Artık güvenli olabilir, çünkü paylaşılan erişimi tek bir yığına serileştirme sorumluluğunu istemciye aktarır. Özellikle, ayrı yığın nesneleri varsa herhangi bir çalışma gerekmez. Ortak bir yığın kullanılıyorsa, istemci erişimi seri hale getirmelidir. Fonksiyonun içinde bir kilit kullanmak yeterli değildir: sadece bir yığını kilitleyen bir malloc * düşünün ve sonra bir sinyal gelir ve aynı işaretçide malloc'u çağırır: kilitlenme: sinyal devam edemez ve istemci kesintiye uğradı.

Genel olarak, kilitler işleri iş parçacığı için güvenli hale getirmez .. aslında müşteri tarafından sahip olunan bir kaynağı uygunsuz bir şekilde yönetmeye çalışarak güvenliği yok eder. Kilitleme nesne üreticisi tarafından yapılmalıdır, kaç nesne oluşturulduğunu ve nasıl kullanılacağını bilen tek kod budur.


"Bu nedenle eşzamanlı-güvenli (genellikle iş parçacığı-güvenli) yeniden giriş anlamına gelir." Bu, "İş parçacığı açısından güvenli ancak yeniden girmeyen" Wikipedia örneğiyle çelişiyor .
Maggyero

3

Listelenen noktalar arasındaki "ortak iş parçacığı" (pun aim !?), işlevin aynı işleve yinelenen veya eşzamanlı çağrıların davranışını etkileyecek hiçbir şey yapmaması gerektiğidir.

Örneğin, statik veri tüm iş parçacıklarına ait olduğundan bir sorundur; bir çağrı statik bir değişkeni değiştirirse, tüm evreler değiştirilmiş verileri kullanır, böylece davranışlarını etkiler. Kendi kendini değiştiren kod (nadiren karşılaşılmasına ve bazı durumlarda engellenmesine rağmen) bir sorun olacaktır, çünkü birden fazla iş parçacığı olmasına rağmen, kodun yalnızca bir kopyası vardır; kod da temel statik verilerdir.

Esasen tekrar girebilmek için, her evre işlevi tek kullanıcıymış gibi kullanabilmelidir ve bir evre başka bir evrenin davranışını belirleyici olmayan bir şekilde etkileyebiliyorsa durum böyle değildir. Öncelikle bu, işlevin üzerinde çalıştığı ayrı veya sabit verilere sahip her bir iş parçacığını içerir.

Bütün söylenenler, nokta (1) mutlaka doğru değildir; örneğin, meşru bir şekilde ve tasarım gereği, aşırı özyinelemeye karşı korumak veya bir algoritmayı profillemek için bir özyineleme sayısını korumak için statik bir değişken kullanabilirsiniz.

İş parçacığı açısından güvenli bir işlevin yeniden girilmesi gerekmez; bir kilitle yeniden girmeyi özellikle önleyerek iplik güvenliğini sağlayabilir ve nokta (6) böyle bir işlevin yeniden girmediğini söyler. Nokta (6) ile ilgili olarak, kilitlenen bir iplik-emniyet fonksiyonunu çağıran bir fonksiyon, özyinelemede kullanım için güvenli değildir (ölü kilitlenecektir) ve bu nedenle eşzamanlılık için güvenli olsa da, reentrant olduğu söylenmez ve birden fazla iş parçacığının program sayaçlarını aynı anda böyle bir işleve sahip olabilmesi (yine kilitli bölge ile değil) anlamında yeniden girilebilir. Bu, iplik güvenliğini reentarncy'den ayırmaya yardımcı olabilir (veya belki de karışıklığınıza katkıda bulunur!).


1

"Ayrıca" sorularınızın cevapları "Hayır", "Hayır" ve "Hayır" dır. Bir işlev özyinelemeli ve / veya iş parçacığı için güvenli olduğundan yeniden giriş yapmaz.

Bu tür işlevlerin her biri teklif ettiğiniz tüm noktalarda başarısız olabilir. (5. noktadan% 100 emin olmasam da).


1

"İş parçacığı için güvenli" ve "yeniden giriş" terimleri yalnızca ve tam olarak tanımlarının söylediği anlamına gelir. Bu bağlamda "güvenli" yalnızca aşağıda tanımladığınız tanımın ne olduğu anlamına gelir .

Burada "güvenli" kesinlikle, daha geniş anlamda, verilen bir işlevi belirli bir bağlamda çağırmanın uygulamanızı tamamen hortumlamayacağı anlamına gelmez. Tamamen, bir işlev çok iş parçacıklı uygulamanızda istenen etkiyi güvenilir bir şekilde üretebilir, ancak tanımlara göre yeniden giriş veya iş parçacığı açısından güvenli olamaz. Tersine, çok işlevli uygulamanızda çeşitli istenmeyen, beklenmedik ve / veya öngörülemeyen etkiler üretecek şekilde yeniden giriş işlevlerini çağırabilirsiniz.

Yinelemeli işlev herhangi bir şey olabilir ve Re-entrant, iş parçacığı için daha güçlü bir tanıma sahiptir, bu nedenle numaralandırılmış sorularınızın yanıtlarının hepsi hayırdır.

Yeniden giriş tanımını okumak, onu değiştirmek için dediğiniz şeyin ötesinde hiçbir şeyi değiştirmeyecek bir işlev olarak özetleyebilir. Ancak sadece özete güvenmemelisiniz.

Çok iş parçacıklı programlama genel durumda oldukça zordur . Birinin kodunun yeniden girildiğini bilmek bu zorluğun sadece bir parçasıdır. İplik güvenliği bir katkı maddesi değildir. Yeniden giriş işlevlerini bir araya getirmeye çalışmak yerine, genel bir iş parçacığı için güvenli tasarım deseni kullanmak ve programınızdaki her iş parçacığı ve paylaşılan kaynakları kullanımınıza rehberlik etmek için bu deseni kullanmak daha iyidir .

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.