当前位置: 首页 > news >正文

如何做单页网站广告投放平台都有哪些

如何做单页网站,广告投放平台都有哪些,平板电脑网站模板,海口网格员文章目录 内核定时器概念在Linux驱动模块中使用定时器软定时器(Soft Timers)jiffies 含义高精度定时器(High Resolution Timers) 实现倒计时字符设备驱动 内核定时器概念 在 Linux 内核中,定时器是用来管理和调度延迟…

文章目录

    • 内核定时器概念
    • 在Linux驱动模块中使用定时器
      • 软定时器(Soft Timers)
      • jiffies 含义
      • 高精度定时器(High Resolution Timers)
    • 实现倒计时字符设备驱动

内核定时器概念

在 Linux 内核中,定时器是用来管理和调度延迟操作的机制。Linux 内核提供了几种不同类型的定时器,每种定时器都有不同的特点和用途。以下是一些主要的定时器类型和相关概念:

  1. POSIX 定时器

    • 这是一个基于 POSIX 标准的定时器,提供了一种用户空间的定时器接口。通过 timer_create()timer_settime()timer_gettime() 等系统调用,用户空间程序可以创建和管理定时器。
  2. 高精度定时器 (High Resolution Timers)

    • 高精度定时器可以提供比普通定时器更高的时间精度。它们使用 hrtimer API 来实现,适用于需要非常精确定时的场景,比如实时系统。
  3. 软定时器 (Soft Timers)

    • 软定时器是内核中的定时器,用于调度执行内核中的延迟操作。它们主要通过 mod_timer()del_timer() 等 API 进行管理。软定时器通常用于处理网络数据包或其他延迟任务。
  4. 延迟队列 (Delay Queues)

    • 延迟队列是一种数据结构,用于在内核中排队等待延迟处理的任务。通过 init_timer()add_timer() 等函数,可以将任务添加到延迟队列中,等待指定时间后执行。
  5. 定时器回调

    • 当定时器到期时,会调用相应的回调函数来执行预定的操作。回调函数通常会在内核态执行,进行一些需要延迟处理的任务。

定时器在内核中的实现涉及到多种机制,包括定时器队列、定时器中断以及内核调度机制等。具体使用和实现细节可以参考 Linux 内核文档和源代码。

在Linux驱动模块中使用定时器

在 Linux 驱动模块中使用定时器,通常有两种主要方式:使用软定时器和高精度定时器。

软定时器(Soft Timers)

软定时器在内核驱动中使用时,通常涉及到 timer_list 结构和相关 API。

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/timer.h>
#include <linux/init.h>static struct timer_list my_timer;void timer_callback(struct timer_list *t)
{printk(KERN_INFO "Timer callback function called.\n");
}static int __init my_module_init(void)
{printk(KERN_INFO "Module initialized.\n");printk(KERN_INFO "System HZ value: %d\n", HZ);// 初始化定时器timer_setup(&my_timer, timer_callback, 0);// 设置定时器超时值(例如 500ms)mod_timer(&my_timer, jiffies + msecs_to_jiffies(500));return 0;
}static void __exit my_module_exit(void)
{// 删除定时器del_timer(&my_timer);printk(KERN_INFO "Module exited.\n");
}module_init(my_module_init);
module_exit(my_module_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("Marxist");
MODULE_DESCRIPTION("A simple Linux driver with a timer.");

关键点说明

  • timer_setup 函数用于初始化 timer_list 结构体并设置回调函数。
  • mod_timer 函数用于设置定时器的超时时间。
  • del_timer 函数用于删除定时器,防止模块卸载时定时器仍在执行。

效果如图:

其中 printk(KERN_INFO "System HZ value: %d\n", HZ); 输出当前系统的时钟中断频率,与jiffies 相关

在这里插入图片描述

jiffies 含义

在 Linux 内核中,jiffies 是一个用于表示系统启动以来的时间的全局计数器,它以“滴答”(tick)为单位。jiffies 是内核中时间管理的一个基本概念,广泛用于定时器和延迟操作。

定义:jiffies 是一个计数器,表示自系统启动以来经过的“时钟滴答”数。每个滴答的时间长度由系统的时钟中断频率决定,通常是 1 毫秒(即 1000 Hz)或 10 毫秒(即 100 Hz),但具体取决于内核配置。

单位jiffies 的单位是系统时钟滴答。系统时钟滴答的频率(即每秒钟中断的次数)由内核配置中的 HZ 参数决定。例如,如果 HZ 设置为 1000,那么每秒会有 1000 个滴答,每个滴答大约是 1 毫秒。

计算时间:使用 jiffies 可以计算时间间隔。例如,如果你要设置一个定时器在 500 毫秒后触发,可以使用以下代码:

mod_timer(&my_timer, jiffies + msecs_to_jiffies(500));

这里,msecs_to_jiffies 函数将 500 毫秒转换为相应的 jiffies 数量。

溢出:由于 jiffies 是一个 unsigned long 类型的变量,它可能会在长时间运行后溢出。在现代 Linux 内核中,jiffies 的溢出问题一般不会对大多数应用造成问题,因为内核设计考虑了这个问题并进行了处理。

转换函数

  • jiffies_to_msecs(jiffies):将 jiffies 转换为毫秒。
  • jiffies_to_timespec(jiffies):将 jiffies 转换为 timespec 结构。
  • msecs_to_jiffies(milliseconds):将毫秒转换为 jiffies

高精度定时器(High Resolution Timers)

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/hrtimer.h>
#include <linux/ktime.h>
#include <linux/init.h>static struct hrtimer my_hrtimer;
static enum hrtimer_restart hrtimer_callback(struct hrtimer *timer)
{printk(KERN_INFO "High resolution timer callback function called.\n");return HRTIMER_NORESTART; // 不重复定时
}static int __init my_module_init(void)
{printk(KERN_INFO "Module initialized.\n");// 初始化高精度定时器hrtimer_init(&my_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);my_hrtimer.function = hrtimer_callback;// 设置定时器超时值(例如 500ms)ktime_t ktime = ktime_set(0, 500 * 1000000); // 500mshrtimer_start(&my_hrtimer, ktime, HRTIMER_MODE_REL);return 0;
}static void __exit my_module_exit(void)
{// 删除高精度定时器int ret = hrtimer_cancel(&my_hrtimer);if (ret)printk(KERN_INFO "The high resolution timer was still active.\n");printk(KERN_INFO "Module exited.\n");
}module_init(my_module_init);
module_exit(my_module_exit);MODULE_LICENSE("GPL");
MODULE_AUTHOR("Marxist");
MODULE_DESCRIPTION("A simple Linux driver with a high resolution timer.");

关键点说明

  • hrtimer_init 函数用于初始化高精度定时器。
  • hrtimer_start 函数用于设置高精度定时器的超时时间。
  • ktime_set 用于创建高精度时间值。
  • hrtimer_cancel 函数用于取消高精度定时器。

效果如下:

在这里插入图片描述

实现倒计时字符设备驱动

#include <linux/init.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/uaccess.h>
#include <linux/device.h>
#include <linux/semaphore.h>
#include <linux/timer.h>
#include <linux/atomic.h> 
#define DEVICE_NAME "countdown_device"static atomic_t counter = ATOMIC_INIT(0);static int major_number;
static struct class *my_class = NULL;
static struct device *my_device = NULL;
static struct cdev mydev;             // 声明 cdev 结构体
static struct timer_list my_timer;    // 声明定时器
static struct semaphore my_semaphore; // 定义信号量
static int count_val = 30;            // 倒计时初始值// 定时器回调函数
void timer_callback(struct timer_list *t)
{count_val= atomic_read(&counter);// 每秒 -1if (count_val > 0){atomic_dec(&counter);printk("mytimer : %d",atomic_read(&counter));// 重新设置定时器以在 1 秒后触发mod_timer(&my_timer, jiffies + msecs_to_jiffies(1000));}else count_val = -1; // 代表结束
}static int device_open(struct inode *inode, struct file *file)
{printk(KERN_INFO "Device opened\n");// 初始化定时器 ,并开启定时任务timer_setup(&my_timer, timer_callback, 0);mod_timer(&my_timer, jiffies + msecs_to_jiffies(1000));return 0;
}static int device_release(struct inode *inode, struct file *file)
{printk(KERN_INFO "Device closed\n");// 删除定时器del_timer_sync(&my_timer);return 0;
}static ssize_t device_read(struct file *filp, char __user *buffer, size_t len, loff_t *offset)
{int count_val_copy;count_val_copy = atomic_read(&counter);printk("begin read new val: %d", count_val_copy);// 将数据从内核空间拷贝到用户空间if (copy_to_user(buffer, &count_val_copy, sizeof(count_val_copy))){printk("copy_to_user error");return -EFAULT;}return sizeof(count_val_copy);
}static ssize_t device_write(struct file *filp, const char __user *buffer, size_t len, loff_t *offset)
{char buf[64];int new_value;// 获取信号量if (down_interruptible(&my_semaphore)){return -ERESTARTSYS;}// 从用户空间复制数据if (copy_from_user(buf, buffer, len)){up(&my_semaphore);return -EFAULT;}buf[len] = '\0';if (sscanf(buf, "%d", &new_value) == 1){count_val = new_value; // 从用户空间获取到倒计时的值}printk("write new val is %d",count_val);// 释放信号量up(&my_semaphore);//重新给原子变量赋值atomic_set(&counter, count_val);  return len;
}static struct file_operations fops = {.open = device_open,.release = device_release,.read = device_read,.write = device_write,
};static int __init test_init(void)
{int retval;dev_t dev;printk(KERN_INFO "module init success\n");// 初始化信号量sema_init(&my_semaphore, 1);// 1. 动态分配主次设备号retval = alloc_chrdev_region(&dev, 0, 1, DEVICE_NAME);if (retval < 0){printk(KERN_ERR "Failed to allocate major number\n");goto fail_alloc_chrdev_region;}major_number = MAJOR(dev);printk(KERN_INFO "major number is: %d, minor number is: %d\n", major_number, MINOR(dev));// 2. 初始化 cdev 结构体并添加到内核cdev_init(&mydev, &fops);retval = cdev_add(&mydev, dev, 1);if (retval < 0){printk(KERN_ERR "Failed to add cdev\n");goto fail_cdev_add;}// 3. 创建设备类my_class = class_create(THIS_MODULE, "my_class");if (IS_ERR(my_class)){printk(KERN_ERR "Failed to create class\n");retval = PTR_ERR(my_class);goto fail_class_create;}// 4. 申请设备,内核空间就会通知用户空间的 udev 进行创建设备,驱动程序本身自己是创建不了文件的!my_device = device_create(my_class, NULL, dev, NULL, DEVICE_NAME);if (IS_ERR(my_device)){printk(KERN_ERR "Failed to create device\n");retval = PTR_ERR(my_device);goto fail_device_create;}printk(KERN_INFO "my_char_device: module loaded\n");return 0;fail_device_create:class_destroy(my_class);
fail_class_create:cdev_del(&mydev);
fail_cdev_add:unregister_chrdev_region(dev, 1);
fail_alloc_chrdev_region:return retval;
}static void __exit test_exit(void)
{dev_t dev = MKDEV(major_number, 0);if (my_device)device_destroy(my_class, dev);if (my_class)class_destroy(my_class);cdev_del(&mydev);unregister_chrdev_region(dev, 1);printk(KERN_INFO "my_char_device: module unloaded\n");
}module_init(test_init);
module_exit(test_exit);
MODULE_AUTHOR("Marxist");
MODULE_LICENSE("GPL");

用户端

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>#define DEVICE_PATH "/dev/countdown_device"int main()
{int fd;char buffer[64];int count_val = 60;  // 倒计时初始值ssize_t bytes_written, bytes_read;int res_val;// 打开设备文件fd = open(DEVICE_PATH, O_RDWR);if (fd < 0){perror("Failed to open the device");return errno;}// 写入倒计时初始值snprintf(buffer, sizeof(buffer), "%d", count_val);bytes_written = write(fd, buffer, strlen(buffer));if (bytes_written < 0){perror("Failed to write to the device");close(fd);return errno;}printf("Written %d to the device\n", count_val);// 进行倒计时读取输出while (1){// 读取当前倒计时值bytes_read = read(fd, &res_val, sizeof(res_val));if (bytes_read < 0){perror("Failed to read from the device");close(fd);return errno;}// 打印当前倒计时值printf("Current countdown value: %d\n", res_val);// 休眠1秒sleep(1);// 判断倒计时是否结束if (res_val <= 0){printf("Countdown finished.\n");break;}}// 关闭设备文件close(fd);return 0;
}

效果如图:在内核中,使用定时器每秒对原子变量的值减-1

在这里插入图片描述

http://www.zhongyajixie.com/news/24656.html

相关文章:

  • 草桥做网站的公司怎么在百度上发布广告
  • 怎么建设游戏试玩平台网站搭建网站基本步骤
  • 商务网站制作工程师关键词排名推广怎么做
  • 射阳建设网站多少钱百度seo培训
  • 外发加工网是真的桂平seo快速优化软件
  • 扬州专业做网站推广关键词
  • 禅城网站建设哪家好seo快速优化软件
  • 网站制作自助seo公司排名
  • 单网页网站制作百度竞价推广效果怎么样
  • 做蛋糕网站的优点企业qq
  • 采集做网站今日最新新闻
  • 做片头的网站北京关键词排名推广
  • 网站运营建设百度搜索引擎api
  • 网站建设哪个软件好百度关键词搜索怎么收费
  • 珠海新盈科技有限公司 网站建设百度知道官网首页登录入口
  • 论坛网站建设模板百度开店怎么收费
  • 阿里云企业邮箱怎么注册seo搜索引擎优化是做什么的
  • 建站之星做的网站如何导出如何推广网上国网
  • 菏泽+网站建设公司seo公司推荐推广平台
  • 家用机能否做网站服务器厦门seo管理
  • 网站开发技术指标是什么自助建站官网
  • 天堂资源地址在线官网下载张掖seo
  • bl做视频网站又有什么新病毒出现了
  • 有那些网站可以做担保交易的网络广告策划的步骤
  • 政和网站建设wzjseo班级优化大师下载安装最新版
  • 红酒网站模板下载职业教育培训机构排名前十
  • 淘宝客赚钱网站青岛网络科技公司排名
  • 做网站会员金字塔系统百度关键词搜索指数查询
  • 在百度搜索到自己的网站搜索引擎网站优化推广
  • 现在那个网站做视频最赚钱知乎seo