2010-09-29 42 views
17

Tôi sử dụng pthread_create để tạo ra một số chủ đề con. Tại một thời điểm, các chủ đề chính muốn giết tất cả các chủ đề con hoặc sẽ có phân đoạn falut. Tôi nên sử dụng chức năng nào để hoàn thành chức năng đó? Tôi đã tìm kiếm câu trả lời từ google và có chức năng như pthread_kill. Nhưng tôi không biết tôi nên gửi tín hiệu nào cho chủ đề con để giết chúng. Môi trường chạy của tôi là RHEL 5.4 và ngôn ngữ lập trình là C.Đối với pthread, Làm thế nào để giết chủ đề con từ chủ đề chính

+2

wow, hãy xóa tất cả chuỗi vì sẽ có một segfault? Bạn đang giỡn hả? Tôi sẽ không bao giờ bởi một chút mã được xử lý như thế. –

+1

Nói thật, tôi gdb dump cốt lõi được tìm thấy khi các chủ đề chính thoát khỏi đối tượng toàn cầu đã được deconstructed. Vì vậy, một số chủ đề con hiện tại có thể sử dụng một biến và phân đoạn lỗi được in trên màn hình của tôi. Mặc dù, logic là đúng và phân đoạn lỗi sẽ không có bất kỳ hiệu ứng nào trên chương trình của tôi vì nó đã hoàn thành. – terry

+2

Khắc phục logic. Nếu các chủ đề khác vẫn đang làm công việc hữu ích, tại sao bạn đang cố gắng chấm dứt chương trình? Nếu các chủ đề khác vẫn cần các đối tượng này ngay cả khi 'main' nằm ngoài phạm vi, tại sao chúng lại được phân bổ trên' main's stack? –

Trả lời

20

Có thể "hủy" một chuỗi bằng cách sử dụng pthread_cancel. Tuy nhiên, đây không phải là cách thực hành tốt nhất mặc dù trong những hoàn cảnh khắc nghiệt như SEGFAULT, nó có thể được kết hợp một cách tiếp cận hợp lý.

+1

Có một ví dụ trong url này http://linux.die.net/man/3/pthread_cleanup_push – enthusiasticgeek

+4

Tại sao 'pthread_cancel' không được coi là thực tiễn tốt nhất? Và nếu nó không phải là thực hành tốt nhất, là gì? – darnir

6

Bạn nên gửi SIG_TERM cho mỗi chủ đề của bạn, sử dụng

int pthread_kill(pthread_t thread, int sig); 

Một cách nhanh chóng để thoát khỏi tất cả các chủ đề (ngoài chính) là fork() và tiếp tục đi với đứa trẻ.
Không siêu sạch ...

if (fork()) exit(0); // deals also with -1... 
24

Nói chung, bạn không thực sự muốn giết dữ dội một sợi con, nhưng thay vào đó bạn muốn hỏi nó chấm dứt. Bằng cách đó bạn có thể chắc chắn rằng đứa trẻ đang bỏ ở một nơi an toàn và tất cả các nguồn lực của nó được làm sạch.

Tôi thường làm điều này với một phần nhỏ trạng thái chia sẻ giữa cha mẹ và con để cho phép phụ huynh giao tiếp "yêu cầu thoát" cho từng đứa trẻ. Điều này chỉ có thể là một giá trị boolean cho mỗi đứa trẻ, được bảo vệ bởi một mutex. Trẻ kiểm tra định kỳ giá trị này (mỗi vòng lặp lặp lại, hoặc bất kỳ điểm kiểm tra thuận tiện nào bạn có trong chuỗi con của bạn). Khi nhìn thấy "quit_request" là đúng, chủ đề con dọn dẹp và gọi pthread_exit.

Về phía phụ huynh, các "kill_child" thói quen trông giống như sau:

acquire shared mutex 
set quit_request to true 
pthread_join the child 

Các pthread_join có thể mất một thời gian, tùy thuộc vào tần suất mà đứa trẻ sẽ kiểm tra nó bỏ yêu cầu. Hãy chắc chắn rằng thiết kế của bạn có thể xử lý bất kỳ sự chậm trễ nào có thể.

+0

Trong khi thực hành tốt để có được một mutex trước khi sửa đổi bất kỳ bộ nhớ nào được chia sẻ giữa các chủ đề, thực tế rằng đây là một lá cờ duy nhất đang được kiểm tra cho tình trạng khác không (hoặc sai), có nghĩa là bạn không thực sự cần để lấy một mutex. Trong trường hợp này, có thực sự là không có nhiều mà có thể đi sai từ một phối cảnh dữ liệu thống nhất. –

+2

@Brent: [Câu hỏi này] (http://stackoverflow.com/questions/21183261/is-a-race-condition-possible-when-only-one-thread-writes-to-a-bool-variable-in -c) cho thấy một ví dụ mà ngay cả một lá cờ được viết một lần có thể dẫn đến một tình trạng đua sau khi tối ưu hóa complier. – dshepherd

+0

Đẹp, công trình này tuyệt vời. – djthoms

2

Bạn có thể sử dụng biến toàn cục cho toàn bộ chương trình.

int _fCloseThreads;

Đặt thành 1 khi bạn muốn chủ đề thoát khỏi thực thi. Có các chủ đề kiểm tra biến đó trong "vòng lặp" của chúng và độc đáo bỏ khi nó được đặt thành 1. Không cần phải bảo vệ nó bằng một mutex.

Bạn cần đợi các chủ đề thoát. Bạn có thể sử dụng tham gia. Một cách khác là tăng một bộ đếm khi một luồng vào proc chủ đề của nó và sau đó làm hỏng bộ đếm khi nó thoát ra. Bộ đếm cần phải là một loại toàn cầu. Sử dụng opc nguyên tử trên bộ đếm. Các chủ đề chính, sau khi thiết lập fCloseThreads, có thể chờ đợi trên truy cập để đi đến số không bằng cách lặp, ngủ, và kiểm tra số lượng.

Cuối cùng, bạn có thể kiểm tra pthread_cleanup_push và bật. Chúng là một mô hình cho phép một luồng để hủy bỏ bất cứ nơi nào trong mã của nó (sử dụng một longjump) và sau đó gọi một hàm làm sạch cuối cùng trước khi thoát khỏi threadproc. Bạn cài đặt cleanup_push ở đầu threadproc và cleanup_pop ở phía dưới, tạo một hàm thư giãn, và sau đó tại một số điểm hủy bỏ, một chuỗi bị hủy bỏ bởi một lệnh gọi tới pthread_cancel() sẽ trở lại threadproc và gọi hàm relax.

+1

http://linux.die.net/man/3/pthread_cleanup_push có một ví dụ. – enthusiasticgeek

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