2014-09-22 14 views
6

Posix iş parçacığı kullanırken, ana iş parçacığının, çalışan iş parçacıklarının neden olduğu hatalardan (örneğin, işaretlenmemiş boş göstergeler, sıfıra bölme, vb.) "Korunmasını" sağlamanın bir yolu vardır. "Çalışan iş parçacığı" ile pthread_create() tarafından oluşturulan bir posix iş parçacığı kastediyorum.Ana parçacığın iş parçacığındaki hatalardan korunması

Maalesef istisnalar kullanamaz - yani hayır "catch" vb İşte

benim test programı (C++): Yukarıdaki örnekte

void* workerThreadFunc(void* threadId) { 
    int* a = NULL; 
    *a = 5; //Error (segmentation fault) 
    pthread_exit(NULL); 
} 

int main() { 
    cout << "Main thread start" << endl; 

    pthread_t workerThread; 
    pthread_attr_t attr; 
    pthread_attr_init(&attr); 
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 
    pthread_create(&workerThread, &attr, workerThreadFunc, (void*)0); 
    pthread_join(workerThread, NULL); 

    cout << "Main thread end" << endl; 
} 

, workerThread kaynaklanan hata olacak tüm programı sonlandırmak. Ancak, ana iş parçacığının bu hataya rağmen çalışmaya devam etmesini istiyorum. Bunu başarmak mümkün mü? (Yani "hiçbir istisna" egemenliği altında düşebilir rağmen) sistem varsayarsak

+0

'Ne yazık ki, istisnaları kullanamıyoruz - yani "yakalama" vb. - tabi ki yapabilirsin. İstisna, onu oluşturan parçacığa atılacaktır. –

+0

Diğer thread'ları istisnalar/hatalardan 'korumak' için en iyi yol, onları düzeltmek ya da algılanmamak ve ele alınmamak/işlemden geçirilmek/saklamaktır. –

+0

Not - Yukarıdaki örnekte, henüz oluşturulmamış bir konuya katılmaya çalışıyorsunuz. –

cevap

8

Bana öyle geliyor ki, iş parçacığı değil, birden çok işlem kullanıyor olmalısınız. Bağımsız süreçler, diğer süreçlerde meydana gelen bu tür hatalardan otomatik olarak korunur.

Yalnızca paylaşmayı düşündüğünüz belleği paylaşmanın ek yararına sahip olan iş parçacıkları arasında veri aktarmak için boruları veya paylaşılan belleği (veya IPC'nin diğer formlarını) kullanabilirsiniz, böylece işçinin "iş parçacığında" bir hata duramaz ayrı bir adres alanı bulunan ayrı bir süreç, çünkü ana "parçacığı" istifi üzerinde.

İş parçacıkları yararlı olabilir, ancak birkaç farklı dezavantajla birlikte gelir, bazen ayrı işlemlerde çalıştırılması daha uygundur.

+0

"İşlem" ile, örnek vermek istediğiniz anlamına gelir. le çatal()? – Martin

+0

Evet, 'fork()' yeni alt süreçler master'dan ve ya exec() 'ya işçiler için farklı bir yürütülebilir dosya çalıştırıyor ya da aynı yürütülebilir dosyayı çalıştırmaya devam ediyorlar ancak çocukların" işçi "modunda çalışmasını sağlayın. –

4

bir şekilde bir POSIX tür sinyalleri kullanır, daha sonra POSIX diyor ki:

kuşağının zamanda

, bir belirleme olacak İşlemin veya işlem içindeki belirli bir iş parçacığı için sinyalin üretilip üretilmediğini yaptı. Sinyalin üretilmesine neden olan iş parçacığı için, bir donanım arızası gibi belirli bir iş parçacığına atfedilebilecek bazı eylemlerle üretilen sinyaller oluşturulmalıdır.

Yani bir pthread bazında vb SIGSEGV, SIGFPE, kolu (ama sadece tüm süreç için bir sinyal işleyici işlevini ayarlayabilirsiniz unutmayın) olabilir. Öyleyse, süreci bir noktaya kadar tek bir pthread'deki bir arıza ile ölü olarak durdurulmasını "koruyabilirsiniz". Elbette ki sorun, sürecin - başarısız pthread'in ve diğer tüm pthreads'ın - hangi durumda olduğunu anlatmak çok zor olabilir. Başarısız pthread birkaç muteks tutuyor olabilir. Başarısız pthread, bir karmaşa içinde bazı paylaşılmış veri yapı (ları) bırakıyor olabilir. Kim bilir ne tür bir arapsaçı şeyleri vardır - pthreads'ler aslında bağımsız değillerse. Diğer pthreads'ların çarpışma ve yanma yerine "incelikle" kapanması için düzenleme yapmak mümkün olabilir. Sonunda, iyi tanımlanmış durumdan biraz daha azına devam etmeyi denemek yerine, tüm ölülerin ölmesini durdurmak daha güvenli olabilir. Tamamen uygulamanın niteliğine bağlı olacaktır. işlemlerin diğer işlemler başarısızlığı daha az hassas olan -

Hiçbir şey hiçbir şey ... ipler süreçlerin daha kolay birbirleriyle iletişim ve başlatmak ve durdurmak için daha az mal olabilir içindir. Bunu yaparken düşünebilirsiniz

5

tek yolu böyle bir sinyal yerine programı iptal edilme, şu anda çalışan iş parçacığı iptal olabilir işleyicisi, bir şeyler kaydediyor:

void handler(int sig) 
{ 
    pthread_exit(NULL); 
} 

signal(SIGSEGV, handler); 

Not Ancak bu pthread_exit olarak güvensiz bir sinyal işleyici içinde güvenli sistem çağrılarından biri olarak listelenmez. Çalıştığınız O/S'ye ve hangi sinyali kullandığınıza bağlı olarak işe yarayabilir.

+0

Teşekkürler, bu en azından şimdilik Basit bir test: Konuştuğunuz güvenlik konularını araştırmaya ihtiyacım var. – Martin

+0

Pthread_exit, bu thread yığınında bir nesne oluşturulduysa ve bu nesnenin tanımlanmış bir yıkıcıya sahip olması durumunda SIGABRT neden oluyor gibi görünüyor. SIGABRT'leri (eğer onları sighandler'de yakalarsa) ya da tam bir program çökmesini yakaladıysanız, örneğin, çok basit bir yapının bir nesnesini bildirirsem bu olur. Eğer bu nesnenin tanımlanmış bir yıkıcıya sahip olması durumunda çökecektir, sadece ~ A() {}. Ancak, bu yok edici tanımlanmadıkça, SIGABRT gönderilmez. Sorun, örneğin bir vektör bildirirse de olur. – Martin

İlgili konular