![](/img/trans.png)
[英]pthread_create returns EAGAIN when the main thread is set sched_deadline scheduling policy
[英]Is SCHED_DEADLINE officially supported in Ubuntu 16.04?
目前我正在運行Ubuntu 16.04,Linux內核版本為4.16。 我編寫了一個虛擬程序,將其調度程序更改為SCHED_DEADLINE。 但是當我嘗試編譯它時,它找不到SCHED_DEADLINE所需的結構和宏的定義。 大多數代碼段都是從這里獲取的 (第24頁)。 以下是測試程序:
#define _GNU_SOURCE
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sched.h>
int main(int argc, char* argv[]) {
struct sched_attr attr;
attr.size = sizeof(attr);
attr.sched_policy = SCHED_DEADLINE;
attr.sched_runtime = 30000000;
attr.sched_period = 100000000;
attr.sched_deadline = attr.sched_period;
if (sched_setattr(gettid(), &attr, 0))
perror("sched_setattr()");
return 0;
}
這是編譯的輸出:
sched_deadline.c: In function ‘main’:
sched_deadline.c:11:20: error: storage size of ‘attr’ isn’t known
struct sched_attr attr;
^
sched_deadline.c:12:21: error: invalid application of ‘sizeof’ to incomplete type ‘struct attr’
attr.size = sizeof(struct attr);
^
sched_deadline.c:13:22: error: ‘SCHED_DEADLINE’ undeclared (first use in this function)
attr.sched_policy = SCHED_DEADLINE;
我的gcc版本:
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.9)
但是, 官方網站上發布的示例代碼適用於我,但示例代碼手動定義了程序中所有需要的宏和系統調用。 我的目標是編譯應用程序而不添加那些應該已經包含在最新內核版本中的定義。 我見過各種各樣的地方說在Linux 3.14.10之后正式支持SCHED_DEADLINE,升級內核會自動解決這個問題。
我試過的事情:
/usr/include/linux/sched.h
。 很明顯,宏是在這個頭文件中定義的,但不知怎的,我的編譯器找不到它。 我也查看了社區中的其他帖子,但所有這些問題都是針對較舊的linux(3.14.10之前的版本)。
您需要包含#include <linux/sched.h>
但是對於sched_setattr()
和gettid()
的定義,請參閱@CraigEstey發布的鏈接
原因是,glibc不會添加linux特定系統調用的函數包裝器。 例如對於gettid()
,在手冊中我們可以讀到:
注意:此系統調用沒有glibc包裝器; 見注意。
Glibc不為此系統調用提供包裝器; 使用系統調用(2)調用它。 此調用返回的線程ID與POSIX線程ID不同
看看這篇文章: https : //lwn.net/Articles/711058/
#define _GNU_SOURCE
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sched.h>
#include <linux/sched.h>
#include <sys/types.h>
struct sched_attr {
uint32_t size;
uint32_t sched_policy;
uint64_t sched_flags;
/* SCHED_NORMAL, SCHED_BATCH */
int32_t sched_nice;
/* SCHED_FIFO, SCHED_RR */
uint32_t sched_priority;
/* SCHED_DEADLINE (nsec) */
uint64_t sched_runtime;
uint64_t sched_deadline;
uint64_t sched_period;
};
int sched_setattr(pid_t pid, const struct sched_attr *attr, unsigned int flags)
{
return syscall(__NR_sched_setattr, pid, attr, flags);
}
int main(int argc, char* argv[]) {
struct sched_attr attr = {
.size = sizeof(attr),
.sched_policy = SCHED_DEADLINE,
.sched_runtime = 30000000,
.sched_period = 100000000,
.sched_deadline = 100000000
};
pid_t tid = syscall(SYS_gettid);
if (sched_setattr(tid, &attr, 0))
perror("sched_setattr()");
return 0;
}
或者更短的代碼,沒有重新定義struct sched_attr
#define _GNU_SOURCE
#include <stdint.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/sched/types.h>
#include <linux/sched.h>
#include <sys/types.h>
int sched_setattr(pid_t pid, const struct sched_attr *attr, unsigned int flags)
{
return syscall(__NR_sched_setattr, pid, attr, flags);
}
int main(int argc, char* argv[]) {
struct sched_attr attr = {
.size = sizeof(attr),
.sched_policy = SCHED_DEADLINE,
.sched_runtime = 30000000,
.sched_period = 100000000,
.sched_deadline = 100000000
};
pid_t tid = syscall(SYS_gettid);
if (sched_setattr(tid, &attr, 0))
perror("sched_setattr()");
return 0;
}
但這需要以root身份執行,否則我得到了sched_setattr(): Operation not permitted
或者應用程序需要具有正確的linux功能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.