C语言函数大全
- y 开头的函数
- 1. yperror
- 1.1 函数说明
- 1.2 演示示例
- 2. yp_match
- 2.1 函数说明
- 2.2 演示示例
- 3. y0【零阶第二类贝塞尔函数】
- 3.1 函数说明
- 3.2 演示示例
- 3.3 运行结果
- 4. y1【一阶第二类贝塞尔函数】
- 4.1 函数说明
- 4.2 演示示例
- 4.3 运行结果
- 5. yn【n 阶第二类贝塞尔函数】
- 5.1 函数说明
- 5.2 演示示例
- 5.3 运行结果
- 6. yield_to
- 6.1 函数说明
- 6.2 演示示例
- 7. yield_to_for
- 7.1 函数说明
- 7.2 演示示例
- 8. yield_to_forced
- 8.1 函数说明
- 8.2 演示示例
- 9. yield_to_if_needed
- 9.1 函数说明
- 9.2 演示示例
- 10. yield_to_when_done
- 10.1 函数说明
- 10.2 演示示例
- 参考
y 开头的函数
1. yperror
1.1 函数说明
函数声明 | 函数功能 |
---|---|
void yperror(char *msg); | 在 UNIX 和 Linux 系统中用于将 NIS (Network Information Service)错误代码转换为相应的错误信息 |
参数:
- msg : 指向一个字符数组的指针,表示 附加的消息
yperror()
函数打印出与最后一次调用 NIS
服务相关联的错误消息,以及任何作为 msg
参数传递的附加消息。
1.2 演示示例
#include <stdio.h>
#include <rpcsvc/ypclnt.h>
int main()
{
char *domain = "example.com";
char *map = "passwd.byname";
int result;
result = yp_match(domain, map, "johndoe", 7, &value, &vallen);
if (result != 0)
{
yperror("Error getting NIS information");
return 1;
}
printf("User data: %s\n", value);
return 0;
}
2. yp_match
2.1 函数说明
函数声明 | 函数功能 |
---|---|
int yp_match(const char *domain, const char *map, const char *key, int keylen, char **val, int *vallen); | 在网络信息服务中使用的函数,用于查找 NIS 数据库中的条目 |
参数:
- domain : 要查询的NIS域名
- map : 要查询的映射表名称
- key : 要查找的键的值
- keylen : 键值的长度
- val : 指向一个指针,该指针将被设置为匹配键的值。如果该键未找到,则指针将被设置为NULL
- vallen: 指向一个整数,它在调用时必须初始化为指定缓冲区大小,返回时包含实际读取的字节数
返回值:
0
:成功找到匹配项YPERR_KEY
:没有找到指定的键YPERR_DOMAIN
:指定的NIS域无法解析YPERR_MAP
:指定的映射表不存在YPERR_YPBIND
:无法联系ypproc_bind进程YPERR_RPC
:RPC故障
2.2 演示示例
详见 1.2 中的演示示例
3. y0【零阶第二类贝塞尔函数】
3.1 函数说明
函数声明 | 函数功能 |
---|---|
double y0(double x); | 计算 x 的零阶第二类贝塞尔函数 |
参数:
- x : 待计算的值
3.2 演示示例
#include <stdio.h>
#include <math.h>
int main()
{
double x = 2.5;
// 计算 x 的零阶第二类贝塞尔函数
double result = y0(x);
printf("y0(%lf) = %lf\n", x, result);
return 0;
}
3.3 运行结果
4. y1【一阶第二类贝塞尔函数】
4.1 函数说明
函数声明 | 函数功能 |
---|---|
double y1(double x); | 计算 x 的一阶第二类贝塞尔函数 |
参数:
- x : 待计算的值
4.2 演示示例
#include <stdio.h>
#include <math.h>
int main()
{
double x = 2.5;
// 计算 x 的一阶第二类贝塞尔函数
double result = y1(x);
printf("y1(%lf) = %lf\n", x, result);
return 0;
}
4.3 运行结果
5. yn【n 阶第二类贝塞尔函数】
5.1 函数说明
函数声明 | 函数功能 |
---|---|
double yn(int n, double x); | 计算 x 的 n 阶第二类贝塞尔函数 |
参数:
- n : 第二类贝塞尔函数的阶数
- x : 待计算的值
5.2 演示示例
#include <stdio.h>
#include <math.h>
int main() {
double x = 1.0;
int n = 2;
// 二阶第二类贝塞尔函数
double value = yn(n, x);
printf("The value of Y_%d(%.2lf) is: %lf\n", n, x, value);
return 0;
}
5.3 运行结果
6. yield_to
6.1 函数说明
函数声明 | 函数功能 |
---|---|
void yield_to(struct task_struct *next); | 它是 Linux 内核中的函数,用于将 CPU 控制权从一个进程转移到另一个进程 |
参数:
- next : 要切换到的进程的任务结构体指针
6.2 演示示例
#include <linux/sched.h>
asmlinkage void sys_yield(void)
{
struct task_struct *next, *prev;
prev = current; // 保存当前进程
next = list_entry(prev->tasks.next, struct task_struct, tasks); // 获取下一个进程
yield_to(next); // 切换到下一个进程
}
上述的这个示例程序是一个系统调用,当用户调用 sys_yield()
时,它将获取下一个进程并将控制权传递给它。
注意,在实际的
Linux
内核代码中,yield_to()
函数有更多的参数和复杂的实现细节,因此这个示例仅仅是为了演示其基本思想。
7. yield_to_for
7.1 函数说明
函数声明 | 函数功能 |
---|---|
void yield_to_for(struct task_struct *prev, struct task_struct *next, long timeout); | 它是 Linux 内核中的一个函数,用于协作式多任务调度 |
参数:
- prev : 指向当前正在运行的任务的
task_struct
结构体- next : 指向即将要运行的任务的
task_struct
结构体。- timeout : 指示当前任务在放弃
CPU
之前应该等待的时间
yield_to_for()
函数的作用是让当前任务主动让出 CPU
,让其他任务有机会运行。
- 如果
timeout
参数大于零,则当前任务会等待指定的时间后再次运行; - 如果
timeout
参数为零,则当前任务会立即重新运行; - 如果
timeout
参数小于零,则当前任务不会自动重新运行,直到其他事件发生时再次被唤醒。
7.2 演示示例
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/timer.h>
static int my_tasklet_id;
static struct timer_list my_timer;
void my_tasklet(unsigned long data)
{
printk("my_tasklet called\n");
}
void my_timer_callback(unsigned long data)
{
struct task_struct *prev = current;
struct task_struct *next = &init_task;
printk("my_timer_callback called\n");
/* 让当前任务主动让出 CPU */
yield_to_for(prev, next, 0);
/* 使用 tasklet 调度后续处理 */
tasklet_schedule(&my_tasklet);
}
int init_module(void)
{
printk("module loaded\n");
/* 注册一个定时器,并在 1 秒后触发回调函数 */
init_timer(&my_timer);
my_timer.function = my_timer_callback;
my_timer.data = 0;
my_timer.expires = jiffies + HZ;
add_timer(&my_timer);
/* 注册一个 tasklet */
my_tasklet_id = __tasklet_hi_schedule(my_tasklet, 0);
return 0;
}
void cleanup_module(void)
{
printk("module unloaded\n");
/* 删除定时器和 tasklet */
del_timer_sync(&my_timer);
tasklet_kill(&my_tasklet);
}
在上述的示例代码中,我们定义了一个定时器和一个 tasklet
,定时器的回调函数 my_timer_callback()
中调用了 yield_to_for()
函数,让当前任务主动让出 CPU
。当定时器到期时,在内核的调度过程中,会先运行其他可运行的任务,然后再次运行当前任务,并执行 tasklet_schedule
,以调度后续处理。
8. yield_to_forced
8.1 函数说明
函数声明 | 函数功能 |
---|---|
void yield_to_forced(struct task_struct *t); | 它是 Linux 内核中的一个函数,用于将当前进程放弃 CPU ,并强制切换到指定的进程 t 所在的 CPU 上执行 |
参数:
- t : 待复制的宽字符串
8.2 演示示例
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
static int __init my_init(void)
{
struct task_struct *p, *next;
printk(KERN_INFO "Start of yield_to_forced example.\n");
// 打印当前进程和它的PID
printk(KERN_INFO "Current process: %s, PID: %d\n", current->comm, current->pid);
// 遍历进程列表,寻找一个不是当前进程的进程
for_each_process(p)
{
if (p != current)
{
next = p;
break;
}
}
// 如果找到了,则将当前进程放弃CPU,并强制切换到找到的进程所在的CPU上执行
if (next)
{
yield_to_forced(next);
printk(KERN_INFO "Switched to process: %s, PID: %d\n", next->comm, next->pid);
}
else
{
printk(KERN_INFO "No other process found.\n");
}
printk(KERN_INFO "End of yield_to_forced example.\n");
return 0;
}
static void __exit my_exit(void)
{
printk(KERN_INFO "Module exit.\n");
}
module_init(my_init);
module_exit(my_exit);
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("ChatGPT");
MODULE_DESCRIPTION("An example of using yield_to_forced function.");
上述的示例代码中,首先遍历进程列表,找一个不是当前进程的进程;如果找到了,则使用 yield_to_forced()
函数将当前进程放弃 CPU
,并强制切换到找到的进程所在的 CPU
上执行。如果找不到这样的进程,则打印一个提示信息。
注意:
yield_to_forced()
函数只有在实时进程中才能使用,否则会导致内核崩溃。因此,在使用该函数时一定要小心。
9. yield_to_if_needed
9.1 函数说明
函数声明 | 函数功能 |
---|---|
void yield_to_if_needed(struct task_struct *prev); | 将 CPU 资源让给其他需要运行的任务 |
参数:
- prev : 当前正在运行的任务结构体的指针
该函数会检查任务 prev
是否需要放弃 CPU
并将控制权交给其他需要运行的任务。如果需要,它将调用 schedule()
函数来选择下一个要运行的任务,并将控制权转移给它。在此过程中,该函数还会执行几个与调度相关的操作,例如检查新选定的任务是否具有更高的优先级,以及将当前任务从 CPU
上下文中删除。
9.2 演示示例
#include <linux/kernel.h>
#include <linux/sched.h>
void my_task_function(void)
{
while (!kthread_should_stop()) {
// Do some work here...
yield_to_if_needed(current);
}
}
struct task_struct *my_task;
int init_module(void)
{
my_task = kthread_create(my_task_function, NULL, "my_task");
if (IS_ERR(my_task)) {
printk(KERN_ERR "Failed to create my_task\n");
return PTR_ERR(my_task);
}
wake_up_process(my_task);
return 0;
}
void cleanup_module(void)
{
kthread_stop(my_task);
}
在上述的示例代码中,
- 首先,我们创建了一个名为
my_task
的内核线程,并将其添加到运行队列中; - 然后,在
my_task_function()
中调用yield_to_if_needed()
函数,以便在必要时放弃CPU
控制权; - 最后,在模块卸载时,我们停止了
my_task
线程。
10. yield_to_when_done
10.1 函数说明
函数声明 | 函数功能 |
---|---|
void yield_to_when_done(struct task_struct *prev, long state); | 它一个 Linux 内核中的函数,它允许当前进程在执行完特定任务时将 CPU 资源让给其他进程,以避免浪费 CPU 时间 |
参数:
- prev : 前一个进程的指针
- state : 进程的状态
10.2 演示示例
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/module.h>
static int my_module_init(void)
{
printk(KERN_INFO "Module initialized.\n");
struct task_struct *prev = current;
long state = TASK_INTERRUPTIBLE;
// 执行某些任务
yield_to_when_done(prev, state);
return 0;
}
static void my_module_exit(void)
{
printk(KERN_INFO "Module exited.\n");
}
module_init(my_module_init);
module_exit(my_module_exit);
MODULE_LICENSE("GPL");
在上述的示例代码中,当模块被加载时,my_module_init()
函数会被调用:
- 首先,在
my_module_init()
函数中,我们打印一条日志; - 然后,获取当前进程的指针并将其赋值给
prev
变量;同时,我们将进程的状态设置为可中断状态(TASK_INTERRUPTIBLE
); - 接着,我们执行某些任务;
- 随后,调用
yield_to_when_done()
函数,将CPU
资源让出; - 最后,
my_module_exit()
函数用于在模块被卸载时清理资源。
参考
- [Bessel Function of the Second Kind]