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, ¶m) == 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, ¶m);
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, ¶m);
DEBUG_FMT("Priority of this process: %d", param.sched_priority);
pthread_getschedparam(pthread_self(), &policy, ¶m);
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.
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
@Ioan: Xem phiên bản cập nhật của câu hỏi. – Dacav
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