2012-05-04 37 views
6

Tôi đang làm việc trên một chương trình có số lượng cố định các luồng trong C bằng cách sử dụng các chuỗi posix.Cách được thông báo khi một sợi đã bị chấm dứt vì một số lỗi

Làm thế nào tôi có thể được thông báo khi một sợi đã bị chấm dứt do một số lỗi?

Có tín hiệu để phát hiện không?

Nếu vậy, trình xử lý tín hiệu có thể tạo một chuỗi mới để giữ số lượng chủ đề giống nhau không?

+0

Tôi tò mò muốn biết nếu có thể được phát hiện mà không có một chủ đề watchdog, nhưng tôi khá chắc chắn bạn phải rời khỏi "giải trí của chủ đề chết" để một người quản lý thread bên ngoài xử lý tín hiệu. (Nhưng tôi đã không bao giờ thực sự cố gắng để làm một điều như vậy, vì vậy tôi có thể sai) – Shahbaz

+1

Tôi tò mò muốn biết những gì bạn có nghĩa là do "chấm dứt do một số lỗi". Nếu một thread ngăn chặn toàn bộ quá trình cùng với tất cả các chủ đề khác segfaults. – alk

+0

im làm việc trên máy chủ web đa luồng, khi số lượng chuỗi ít hơn số cố định, máy chủ chấm dứt. Tôi không biết tại sao các chủ đề đang được chấm dứt trong chương trình, máy chủ phục vụ khoảng 1000 kết nối, sau đó nó chấm dứt. – CodeRed

Trả lời

1
  1. Làm cho chủ đề tách
  2. Nhận họ để xử lý các lỗi một cách duyên dáng. tức là Đóng các mutex, tệp, v.v ...

Sau đó, bạn sẽ không có probolems.

lẽ bắn một tín hiệu USR1 đến các chủ đề chính để nói với nó rằng mọi thứ đã đi hình quả lê (i sẽ nói tits lên!)

1

Tạo chủ đề bằng cách vượt qua con trỏ chức năng để một chức năng trung gian. Bắt đầu hàm trung gian đó một cách không đồng bộ và yêu cầu nó đồng bộ gọi hàm được truyền. Khi hàm trả về hoặc ném một ngoại lệ, bạn có thể xử lý các kết quả theo bất kỳ cách nào bạn muốn.

+0

Điều gì xảy ra nếu luồng nhận tín hiệu 'KILL'? (Hoặc bất kỳ tín hiệu nào lấy đi điều khiển từ 'threadFn' không đồng bộ). Hàm trung gian không thể xử lý các trường hợp như điều khiển sẽ được lấy ra khỏi 'threadFn' không đồng bộ và nó có thể không trở về hàm trung gian –

+0

Chặn tất cả các tín hiệu cho tất cả các luồng của quá trình, nhưng một luồng không làm gì khác ngoài do {sigwaitinfo(); } trong khi (1) ;. Bằng cách này, bạn có thể xử lý các tín hiệu không đồng bộ theo cách được tạo luồ[email protected] – alk

1

Với sự đóng góp mới nhất mà bạn đã cung cấp, tôi đề nghị bạn làm một cái gì đó như thế này để có được số lượng đề một quá trình cụ thể đã started-

#include<stdio.h> 
#define THRESHOLD 50 

int main() 
{ 
    unsigned count = 0; 
    FILE *a; 

    a = popen ("ps H `ps -A | grep a.out | awk '{print $1}'` | wc -l", "r"); 
    if (a == NULL) 
     printf ("Error in executing command\n"); 

    fscanf(a, "%d", &count); 

    if (count < THRESHOLD) 
    { 
     printf("Number of threads = %d\n", count-1); 
      // count - 1 in order to eliminate header. 
      // count - 2 if you don't want to include the main thread 

     /* Take action. May be start a new thread etc */ 
    } 

    return 0; 
} 

Ghi chú:

  • ps H hiển thị tất cả các chuỗi.

  • $1 in cột đầu tiên nơi PID được hiển thị trên hệ thống của tôi Ubuntu. Số cột có thể thay đổi tùy thuộc vào hệ thống

  • Thay a.out nó với tên quá trình của bạn

  • các backticks sẽ đánh giá biểu thức trong họ và cung cấp cho bạn các PID của tiến trình của bạn. Chúng tôi đang tận dụng lợi thế của thực tế là tất cả các chủ đề POSIX sẽ có cùng một PID.

+0

Có lẽ bạn ít nhất có thể sử dụng libprocps chứ không phải là một 'hệ thống()' + 'fscanf()' mà là các hàm khá nguy hiểm để sử dụng. Ngoài ra, bạn có thể xem xét 'gettid()' cung cấp cho bạn mã định danh chuỗi (id công việc Linux) –

1

Tôi nghi ngờ Linux sẽ báo hiệu bạn khi chuỗi bị chết hoặc thoát vì bất kỳ lý do gì. Bạn có thể làm như vậy mặc dù bằng tay.

Đầu tiên, chúng ta hãy xem xét 2 cách cho thread để kết thúc:

  • Nó chấm dứt bản thân
  • Nó chết

Trong phương pháp đầu tiên, các chủ đề chính nó có thể nói với ai đó (nói quản lý chuỗi) rằng nó đang bị chấm dứt. Trình quản lý luồng sau đó sẽ sinh ra một luồng khác.

Trong phương pháp thứ hai, một chuỗi cơ quan giám sát có thể theo dõi xem các chuỗi có đang hoạt động hay không.Này được thực hiện nhiều hơn hoặc ít hơn như thế này:

Thread: 
    while (do stuff) 
     this_thread->is_alive = true 
     work 

Watchdog: 
    for all threads t 
     t->timeout = 0 
    while (true) 
     for all threads t 
      if t->is_alive 
       t->timeout = 0 
       t->is_alive = false 
      else 
       ++t->timeout 
       if t->timeout > THRESHOLD 
        Thread has died! Tell the thread manager to respawn it 
+0

Tôi đồng ý với đề cập đến đầu tiên, nhưng thứ hai bạn có thể rất tốt để giải thích, ý bạn là gì? " nó chết ", nếu chủ đề sẽ không cam kết 'tự tử', mà sẽ được bao phủ bởi possiblity 1, làm thế nào khác nó sẽ kết thúc, nếu không' pthread_cancel() 'ed từ bên ngoài? – alk

+0

@alk, tôi hiểu những gì bạn đang nói. Trong một ứng dụng không gian người dùng Linux nếu một thread phân tách (ví dụ) toàn bộ quá trình chết. Tôi không biết liệu có hệ điều hành nào ở đó không đúng, nhưng ít nhất, trong không gian hạt nhân Linux, một luồng có thể không có lỗi hạt nhân và đây là cách bạn biết nếu nó còn sống hay đã chết . Câu hỏi của OP là "làm thế nào để biết nếu thread được chấm dứt do lỗi?". Tôi cho rằng OP có một tình huống phức tạp hơn trong tay hơn là một chuỗi thoát. Tôi không biết chính xác tình hình là gì nên tôi đã đưa ra một giải pháp chung. – Shahbaz

1

Nếu vì bất cứ lý do người ta không thể đi chữa lành của Ed "chỉ hoạt động đúng" -approach (đó là câu trả lời yêu thích của tôi cho câu hỏi của OP, btw), người lười biếng fox có thể xem xét các macro pthread_cleanup_push()pthread_cleanup_pop() và suy nghĩ về việc bao gồm toàn bộ nội dung của hàm chuỗi ở giữa hai macro này.

1

Cách rõ ràng để biết liệu một chuỗi có được thực hiện hay không là gọi số pthread_join() với chuỗi đó.

// int pthread_join(pthread_t thread, void **retval); 
int retval = 0; 
int r = pthread_join(that_thread_id, &retval); 
... here you know that_thread_id returned ... 

Vấn đề với pthread_join() là, nếu luồng không bao giờ trả về (tiếp tục chạy như mong đợi) thì bạn bị chặn. Do đó, không phải là rất hữu ích trong trường hợp của bạn.

Tuy nhiên, bạn thực sự có thể kiểm tra xem bạn có thể tham gia (tryjoin) như sau:

//int pthread_tryjoin_np(pthread_t thread, void **retval); 
int retval = 0; 
int r = pthread_tryjoin_np(that_thread_id, &relval); 

// here 'r' tells you whether the thread returned (joined) or not. 
if(r == 0) 
{ 
    // that_thread_id is done, create new thread here 
    ... 
} 
else if(errno != EBUSY) 
{ 
    // react to "weird" errors... (maybe a perror() at least?) 
} 
// else -- thread is still running 

Ngoài ra còn có một theo thời gian tham gia mà sẽ chờ đợi cho số lượng thời gian mà bạn chỉ định, giống như một vài giây. Tùy thuộc vào số lượng các chủ đề để kiểm tra và nếu quá trình chính của bạn chỉ ngồi xung quanh khác, nó có thể là một giải pháp. Chặn trên luồng 1 trong 5 giây, sau đó là chuỗi 2 trong 5 giây, v.v ... sẽ là 5.000 giây trên mỗi vòng lặp cho 1000 luồng (khoảng 85 phút để đi xung quanh tất cả các chuỗi với thời gian cần thiết để quản lý mọi thứ ...)

Có một mã mẫu trong trang hướng dẫn sử dụng hàm pthread_timedjoin_np(). Tất cả bạn sẽ phải làm là đặt một vòng lặp xung quanh để kiểm tra từng chủ đề của bạn.

struct timespec ts; 
int s; 

... 

if (clock_gettime(CLOCK_REALTIME, &ts) == -1) { 
/* Handle error */ 
} 

ts.tv_sec += 5; 

s = pthread_timedjoin_np(thread, NULL, &ts); 
if (s != 0) { 
    /* Handle error */ 
} 

Nếu quá trình chính của bạn có những việc khác cần làm, tôi khuyên bạn không nên sử dụng phiên bản hẹn giờ và chỉ lướt qua tất cả các chủ đề nhanh nhất có thể.

Các vấn đề liên quan