2010-07-08 32 views
6

tôi cần phải quản lý một thread pool có những ưu tiên khác nhau, vì vậy tôi đã viết các thủ tục đề khởi động sau đây:pthreads với thời gian thực ưu tiên

static 
int startup(thrd_t *thrd, thrd_sync_t *sync, int prio) 
{ 
    pthread_attr_t attr; 
    int err; 
    struct sched_param param = { 
     .sched_priority = prio 
    }; 

    assert(pthread_attr_init(&attr) == 0); 
    assert(pthread_attr_setschedpolicy(&attr, SCHED_FIFO) == 0); 
    assert(pthread_attr_setschedparam(&attr, &param) == 0); 
    err = pthread_create(&thrd->handler, &attr, thread_routine, (void *)thrd); 
    pthread_attr_destroy(&attr); 

    return err; 
} 

Về nguyên tắc người dùng không có đặc quyền không nên được phép thực thi mã này: cuộc gọi pthread_create() sẽ trả về EPERM vì các tác động bảo mật của việc chạy một luồng có mức độ ưu tiên cao.

Thật bất ngờ nó hoạt động cho người dùng bình thường, nhưng nó không tôn trọng ưu tiên đã cho.

Tôi cố gắng để thay đổi mã bằng cách loại bỏ các pthread_attr_t và bằng cách thiết lập thuộc tính lịch một lần thread đã được tạo:

static 
int startup(thrd_t *thrd, thrd_sync_t *sync, int prio) 
{ 
    pthread_attr_t attr; 
    int err; 
    struct sched_param param = { 
     .sched_priority = prio 
    }; 

    err = pthread_create(&thrd->handler, NULL /*&attr*/, thread_routine, 
         (void *)thrd); 
    if (err != 0) return err; 

    err = pthread_setschedparam(thrd->handler, SCHED_FIFO, &param); 
    if (err != 0) return err; 

    return err; 
} 

Cách tiếp cận này bằng cách này được nhiều khó khăn hơn để quản lý, vì trong trường hợp lỗi tôi cần phải giết các chủ đề mới được tạo ra. Ít nhất nó có vẻ hoạt động đúng với các yêu cầu cấp phép (chỉ root mới có thể thực hiện điều này), nhưng vẫn ưu tiên không được tôn trọng.

Tôi có làm gì sai không?

EDIT

Tôi vừa mới bổ sung thêm đoạn mã sau đây được thực hiện bởi tất cả các chủ đề:

static 
void getinfo() 
{ 
    struct sched_param param; 
    int policy; 

    sched_getparam(0, &param); 
    DEBUG_FMT("Priority of this process: %d", param.sched_priority); 

    pthread_getschedparam(pthread_self(), &policy, &param); 

    DEBUG_FMT("Priority of the thread: %d, current policy is: %d and should be %d", 
       param.sched_priority, policy, SCHED_FIFO); 
} 

Với phương pháp đầu tiên (cụ thể là cách tiếp cận pthread_attr_t) nó quay ra rằng pthread_attr_setschedpolicy là hoàn toàn không hiệu quả, vì mức độ ưu tiên là 0 và chính sách không phải là SCHED_FIFO.

Với phương pháp thứ hai (cụ thể là phương pháp pthread_setschedparam), hàm in dữ liệu dự kiến, nhưng quá trình thực hiện vẫn hoạt động sai.

+1

Làm cách nào để xác định cuộc gọi không được tôn trọng? Tôi đã gặp phải một cái gì đó tương tự, nhưng API chỉ đơn giản là không được thực hiện và thất bại như vậy. – Ioan

+0

@Ioan: Xem phiên bản cập nhật của câu hỏi. – Dacav

+1

OT: không đặt mã bên trong 'assert()'. Nếu điều này được biên dịch với xác nhận bị vô hiệu hóa, mã sẽ không được thực hiện. – bstpierre

Trả lời

8

Tôi nghĩ bạn cũng phải sử dụng pthread_attr_setinheritsched để đảm bảo rằng các thay đổi của bạn cho cài đặt ưu tiên được tính đến. Từ trang người đàn ông:

PTHREAD_INHERIT_SCHED Chỉ định rằng chính sách kế hoạch và các thuộc tính liên quan là được thừa kế từ tạo chủ đề, và lịch trình các thuộc tính trong lập luận attr này đang được bỏ qua.

PTHREAD_EXPLICIT_SCHED Chỉ định rằng chính sách kế hoạch và các thuộc tính liên quan là được thiết lập với các giá trị tương ứng từ đối tượng thuộc tính này.

Và thêm một chút trong man page, bạn có:

Cài đặt mặc định của thuộc tính kế thừa-scheduler trong một thread mới khởi tạo các thuộc tính đối tượng được PTHREAD_INHERIT_SCHED.

+0

Đã hoạt động! Cảm ơn rất nhiều: điều này giải quyết một trong hai vấn đề. Tuy nhiên nó khá là trực quan: nếu tôi chỉ định bạn một ưu tiên, có lẽ đó là vì tôi muốn bạn sử dụng nó, đúng không? :) Bây giờ tôi sẽ tìm ra lý do của hành vi sai: có thể là một lỗi? – Dacav

+0

@Dacav: bạn có thể giải quyết vấn đề thứ hai của mình thêm một chút không? không chắc tôi có được nó. Lỗi trong khu vực đó (nhưng của riêng bạn ;-) là rất khó xảy ra. Bạn đã không nói nhiều về hệ thống bạn đang chạy, nhưng hiện nay việc triển khai luồng được thực sự kiểm tra hàng tỷ lần mỗi ngày. –

+0

cho thời điểm chương trình của tôi chỉ là một giàn giáo: logic kinh doanh thực sẽ được thêm vào sau. Để kiểm tra mức độ ưu tiên, mỗi chuỗi bắt đầu bằng cách đợi trên biến điều kiện, biến này sau đó được phát sóng. Sau đó, mỗi chủ đề giữ viết không có thật trên stderr. Những gì tôi mong đợi là xem tại không có chủ đề ưu tiên cao hơn trước khi chủ đề ưu tiên thấp hơn. Tôi nghi ngờ rằng lõi kép của tôi có trách nhiệm xen kẽ bất ngờ ... Tôi đang nghĩ về một thử nghiệm tốt, ngay bây giờ. – Dacav

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