2011-07-10 20 views
5
// threadA.c 
int main() { 
    int res; 
    pthread_t a_thread; 
    void *thread_result; 

    res = pthread_create(&a_thread, NULL, thread_function, NULL); 
    if (res != 0) { 
     perror("Thread creation failed"); 
     exit(EXIT_FAILURE); 
    } 
    sleep(3); 
    printf("Canceling thread...\n"); 
    res = pthread_cancel(a_thread); 
    if (res != 0) { 
     perror("Thread cancelation failed"); 
     exit(EXIT_FAILURE); 
    } 
    printf("Waiting for thread to finish...\n"); 
    res = pthread_join(a_thread, &thread_result); 
    if (res != 0) { 
     perror("Thread join failed"); 
     exit(EXIT_FAILURE); 
    } 
    exit(EXIT_SUCCESS); 
} 

void *thread_function(void *arg) { 
    int i, res, j; 
    res = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); 
    if (res != 0) { 
     perror("Thread pthread_setcancelstate failed"); 
     exit(EXIT_FAILURE); 
    } 
    res = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); 
    if (res != 0) { 
     perror("Thread pthread_setcanceltype failed"); 
     exit(EXIT_FAILURE); 
    } 
    printf("thread_function is running\n"); 
    for(i = 0; i < 10; i++) { 
     printf("Thread is still running (%d)...\n", i); 
     sleep(1); 
    } 
    pthread_exit(0); 
} 

Çıktı aşağıdaki gibidir:çocuk POSIX iplik iptal edilir nasıl

$ ./threadA 
thread_function is running 
Thread is still running (0)... 
Thread is still running (1)... 
Thread is still running (2)... 
Canceling thread... 
Waiting for thread to finish... 
$ 

3 saniye bekledikten bitirerek ana iş parçacığı çocuk parçacığı ve gerçekten başlar çocuk parçacığı durdurmak için komut pthread_cancel sorunları pthread_join komutu çağrıldıktan sonra iptal yanıtı. Şu anda

, ana iş parçacığı bu döngü içindeki herhangi denetimi deyimi görmüyorum

for(i = 0; i < 10; i++) { 
     printf("Thread is still running (%d)...\n", i); 
     sleep(1); 
    } 

hemen pthread_join sonra, çocuk diş aşağıdaki kod döngü içinde çalışan hattına çalışır Ancak ana iş parçacığı hala çocuk ipliğini iptal edebilir. POSIX multithread sisteminin dahili bir kontrol sistemine sahip olduğunu varsayardım, böylece ana iş parçacığında pthread_join çağrıldığında alt parçacığı sonlandırabilir.

>

Temelde, çocuk diş kendisi herhangi bayrakları kontrol etmeden döngü içinde iptal edilebilir nasıl anlamamız gerekir Soru.

Ayrıca, yanlış bir şey varsa lütfen açıklamamı düzeltin.

cevap

6

Olanak, döngüsünüzde en az bir iptal noktası, sleep (ve muhtemelen iki, printf isteğe bağlı bir iptal noktasıdır) içeriyor olmasıdır.

Gerçekte
if (thread_local_cancellation_flag) { 
    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE); 
    pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED); 
    pthread_exit(PTHREAD_CANCELED); 
} 

işlevi " "bekleme" ya ise iptal isteği gelirse çünkü, ancak, biraz daha karmaşıktır: bir iptal noktası olmak

işlevi benzer mantığı içerir demektir "bazı olayların gerçekleşmesi için engellenmesi (süresinin dolması veya bir soketten giriş gibi), üzerinde harekete geçilmelidir. Bu nedenle, bir çeşit asenkron dağıtım mekanizması gereklidir ve tipik uygulama bunun için sinyaller kullanmaktır, ancak doğru bir şekilde elde edilmesi gerçekten çok zordur ve popüler uygulamalar o kadar iyi değildir. diğer uygulamalar muhtemelen paylaşan glibc'de bazı çirkin köşe durumlarda, bu hata raporu bakın: Senin durumunda

http://sourceware.org/bugzilla/show_bug.cgi?id=12683

ne neredeyse kesinlikle oluyor iplik iken iptali isteği (bir sinyal yoluyla) ulaşır olmasıdır sleep içinde bekleyen ve bir sinyal işleyici çalışır, iptal edilebilir bir işlemin ortasında olduğunu belirler ve iptal isteğinde çalışır.

3

Lütfen ilk önce pthread_cancel kılavuz sayfasını okuyun. Çok açıklıyor. Özellikle sorunuz için, döngü içinde kontrol ifadesi bulunmayacaktır. Linux uygulamasını kontrol etmedim, ancak bunu yapmanın rasyonel olayı, bir iş parçacığı iş parçacığının durdurmak/iptal etmek için bir sinyal göndermesi olurdu. Sinyal işleyicideki ipliğin durumu olduğu tespit edilirse, iptal edilemez ve istek sıraya konur. cancellation point olan bir işlevi çağırdığınızda ve yeni durumun iptal edilebildiği belirlendiğinde, bu sıra kontrol edilir ve kuyruğa alma isteği kuyrukta bulunursa - iş parçacığı iptal edilir. Temel olarak, iptal edilemez durum critical section'dur. Durumunuzda, tüm ipleriniz sleep() numaralı telefonu arayarak iptal edilir, çünkü bu bir iptal noktasıdır. Bakınız pthreads (7).

+0

'pthread_setcanceltype' ve' pthread_setcancelstate' iptal noktaları değildir. İptal durumu yalnızca, iptal türü asenkronize olmadıkça, iptal noktalarında kontrol edilir, bu durumda * MAY * diğer noktalarda kontrol edilir ve kodu senkronize olmayan bir şekilde (ancak zorunlu değildir) kesilir. –

+0

@R ..: İyi nokta. Yanıtı buna göre düzenledim. Teşekkürler. –

İlgili konular