2012-07-18 34 views
5

Tôi đang cố gắng tìm ra cách loại bỏ sự phụ thuộc vào pthread_timedjoin_np vì tôi đang cố gắng xây dựng một số mã trên OSX.thay thế cho pthread_timedjoin_np

Ngay bây giờ tôi có một Hàng đợi các chủ đề mà tôi đang popping, làm điều đó pthread_timedjoin_np và nếu họ không trở lại, họ được đẩy trở lại trên hàng đợi.

Sự kết thúc của thread_function được gọi cho mỗi luồng thực hiện một pthread_exit (0); sao cho luồng nhận được có thể kiểm tra giá trị trả về bằng không.

Tôi nghĩ rằng tôi có thể thử sử dụng pthread_cond_timedwait() để đạt được hiệu ứng tương tự, tuy nhiên tôi nghĩ rằng tôi đang thiếu một bước.

Tôi nghĩ mình có thể tạo công nhân Chỉ báo tín hiệu một điều kiện AND pthread_exit() trong một mutex, và B công nhân có thể đánh thức tín hiệu và sau đó pthread_join(). Vấn đề là, Thread B không biết thread nào đã ném tín hiệu điều kiện. Tôi có cần phải truyền đạt điều đó một cách rõ ràng như một phần của tín hiệu conditonal hay không?

Cảm ơn

Derek

+0

Không phải là một bản sao, nhưng một số các câu trả lời có thể hữu ích: http: // stackoverflow.com/questions/73468/non-blocking-pthread-join – Corbin

Trả lời

1

Hàng đợi của người tiêu dùng sản xuất. Có chủ đề hàng đợi * bản thân, và do đó, kết quả của họ, (nếu có), đến hàng đợi trước khi họ thoát. Chờ đợi trên hàng đợi.

Không bỏ phiếu, không có độ trễ.

Với thiết kế hiện tại của bạn, bạn sẽ phải tham gia() các chuỗi được trả lại nhận được giá trị và để đảm bảo rằng chúng bị hủy.

Có thể bạn có thể di chuyển đến một threadpool thực, nơi các mục công việc được xếp hàng đợi đến các chủ đề không bao giờ chấm dứt, (để loại bỏ luồng/chấm dứt/hủy đầu)?

+0

re: real threadpool..i đã có ý tưởng này trước đây. Tôi đang làm việc trong khuôn khổ Qt và tôi đã sử dụng mô hình hồ bơi/tương lai của mình trước đây, nhưng tôi không chắc chắn liệu tôi có thể sử dụng điều đó trong tên của tính di động của mã này – Derek

+0

Tôi đã cố gắng thực hiện một cái gì đó như điều này - ban đầu chủ đề chính chỉ là ném tất cả các công nhân vào hàng đợi, nhưng tôi đã làm lại nó một chút để làm cho nó trở thành hàng đợi khi chúng được thực hiện, và sau đó ném một tín hiệu điều kiện để cho người khác thread biết để kéo một cái gì đó các chủ đề ra khỏi hàng đợi đó và tham gia nó. – Derek

4

Đây là một thực hiện di động của pthread_timedjoin_np. Đó là một chút tốn kém, nhưng đó là một thay thế đầy đủ thay thế:

struct args { 
    int joined; 
    pthread_t td; 
    pthread_mutex_t mtx; 
    pthread_cond_t cond; 
    void **res; 
}; 

static void *waiter(void *ap) 
{ 
    struct args *args = ap; 
    pthread_join(args->td, args->res); 
    pthread_mutex_lock(&args->mtx); 
    args->joined = 1; 
    pthread_mutex_unlock(&args->mtx); 
    pthread_cond_signal(&args->cond); 
    return 0; 
} 

int pthread_timedjoin_np(pthread_t td, void **res, struct timespec *ts) 
{ 
    pthread_t tmp; 
    int ret; 
    struct args args = { .td = td, .res = res }; 

    pthread_mutex_init(&args.mtx, 0); 
    pthread_cond_init(&args.cond, 0); 
    pthread_mutex_lock(&args.mtx); 

    ret = pthread_create(&tmp, 0, waiter, &args); 
    if (ret) goto done; 

    do ret = pthread_cond_timedwait(&args.cond, &args.mtx, ts); 
    while (!args.joined && ret != ETIMEDOUT); 

    pthread_mutex_unlock(&args.mtx); 

    pthread_cancel(tmp); 
    pthread_join(tmp, 0); 

    pthread_cond_destroy(&args.cond); 
    pthread_mutex_destroy(&args.mtx); 

    return args.joined ? 0 : ret; 
} 

Có thể có lỗi nhỏ vì tôi đã viết nó ngay tại chỗ và không thử nghiệm, nhưng khái niệm là âm thanh.

+0

Trước khi bạn đăng tôi đã thực sự đưa ra một kế hoạch tương tự như Martins, nếu điều đó không có vẻ là làm việc tốt tôi sẽ cung cấp cho một thử. – Derek

+0

Giải pháp của Martin là sạch hơn từ quan điểm không có phí tổn lãng phí và là khái niệm tốt hơn. Mỏ chỉ là một thay thế thả cho chức năng không di động cho phép bạn sửa chữa mã không di động mà không cần thiết kế lại bất cứ thứ gì. –

0

giải pháp với alarm.

pthread sẽ cho phép hủy, vì vậy nó có thể dừng bên ngoài. (Ngay cả với pthread_timedjoin_np).

pthread_timedjoin_np trả lại với ETIMEOUT sau thời gian chờ.

  1. đặt alarm, sử dụng alarm cũng có thể cung cấp tín hiệu "TIMEOUT".
  2. Trong trình xử lý, chỉ cần pthread_cancel. (chỉ thời gian chờ chạy này).
  3. pthread_join trong chủ đề chính.
  4. reset alarm

tôi viết mã kiểm tra ở đây: github