最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Linux內(nèi)核定時(shí)器使用及說(shuō)明

 更新時(shí)間:2025年12月06日 16:33:17   作者:卿相訴七弦  
文章詳細(xì)介紹了Linux內(nèi)核定時(shí)器的特性、核心數(shù)據(jù)結(jié)構(gòu)、時(shí)間相關(guān)轉(zhuǎn)換函數(shù)以及操作API,通過(guò)示例展示了如何編寫(xiě)和使用定時(shí)器,包括按鍵消抖的應(yīng)用

1.Linux內(nèi)核定時(shí)器特征

  1. 依賴(lài)Linux系統(tǒng)心跳節(jié)拍發(fā)生器的定時(shí)器;
  2. 基于未來(lái)的時(shí)間點(diǎn)的一種定時(shí)方式;
  3. 支持多段定時(shí),互不干擾:一段定時(shí)還沒(méi)有完成,可以再啟動(dòng)新一段定時(shí);
  4. 內(nèi)核定時(shí)器支持的是單次定時(shí)方式,不是循環(huán)定時(shí);
  5. 內(nèi)核定時(shí)器定時(shí)精度不高,如果需要高精度定時(shí)需要使用硬件定時(shí)器或使用內(nèi)核高精度定時(shí)器;
  6. 定時(shí)器的超時(shí)處理函數(shù)只會(huì)在注冊(cè)它的CPU上運(yùn)行,不會(huì)存在并發(fā)問(wèn)題。

2.Linux內(nèi)核定時(shí)器核心數(shù)據(jù)結(jié)構(gòu)

內(nèi)核使用struct timer_list表示一個(gè)內(nèi)核定時(shí)器,定義如下:

struct timer_list {
       struct hlist_node entry;                                    //實(shí)現(xiàn)定時(shí)器結(jié)構(gòu)鏈表化管理
       unsigned long             expires;                          //到期時(shí)間點(diǎn)      不是時(shí)長(zhǎng)
       void                     (*function)(unsigned long);        //超時(shí)處理函數(shù)
       unsigned long             data;
       u32               flags;
       int                 slack;
};

重要成員:

到期時(shí)間,基于未來(lái)時(shí)間點(diǎn)的時(shí)鐘節(jié)拍數(shù)。等于定時(shí)時(shí)刻當(dāng)前的時(shí)鐘節(jié)拍計(jì)數(shù)(存儲(chǔ)在系統(tǒng)的全局expires變量jiffies)+定時(shí)時(shí)長(zhǎng)對(duì)應(yīng)的時(shí)鐘節(jié)拍數(shù)量。

示例:從現(xiàn)在開(kāi)始定時(shí)1秒:expires = jiffies + 1*Hz

Hz:表示一秒對(duì)應(yīng)的時(shí)鐘節(jié)拍數(shù)

  • function超時(shí)處理函數(shù),并不是硬件中斷服務(wù)程序。
  • data傳遞給超時(shí)處理函數(shù)的參數(shù),可以把一個(gè)變量的地址轉(zhuǎn)換成unsigned long

3.Linux內(nèi)核時(shí)間相關(guān)轉(zhuǎn)換函數(shù)

定時(shí)使用的不是時(shí)長(zhǎng),是基于未來(lái)時(shí)間點(diǎn),單位是時(shí)鐘節(jié)拍。

HZ宏:1秒對(duì)應(yīng)時(shí)鐘節(jié)拍。

unsigned long msecs_to_jiffies(const unsigned int m)             //把ms轉(zhuǎn)換為時(shí)鐘節(jié)拍
unsigned long usecs_to_jiffies(const unsigned int u)             //把us轉(zhuǎn)換為時(shí)鐘節(jié)拍

示例:定時(shí)2s+200ms+500us

到期時(shí)間:jiffies + 2*HZ+msecs_to_jiffies(200)+msecs_to_jiffies(500)

4.Linux內(nèi)核定時(shí)器操作相關(guān)API

4.1 靜態(tài)定義結(jié)構(gòu)體變量并且初始化(宏):DEFINE_TIMER

頭文件

#include <linux/timer.h>

原型

#define DEFINE_TIMER(_name, _function, _expires, _data)             \

struct timer_list _name = TIMER_INITIALIZER(_function, _expires, _data)

參數(shù)

_name變量名

_function超時(shí)處理函數(shù)

_expires到期時(shí)間,一般在啟動(dòng)定時(shí)前需要重新初始化。

_data傳遞給超時(shí)處理函數(shù)的參數(shù)

功能

定義一個(gè)定時(shí)器結(jié)構(gòu)并且初始化function, expires, data成員。

4.2 動(dòng)態(tài)初始化定時(shí)器(宏):setup_timer

頭文件

#include <linux/timer.h>

原型

#define setup_timer(timer, fn, data)      __setup_timer((timer), (fn), (data), 0)

參數(shù)

timer定時(shí)器結(jié)構(gòu)指針

n超時(shí)處理函數(shù)

data超時(shí)處理函數(shù)參數(shù)

功能

運(yùn)行時(shí)初始化定時(shí)器

struct timer_list btn_timer;
setup_timer(&btn_timer, fn, data)
btn_timer.expires = jiffies+定時(shí)時(shí)長(zhǎng)對(duì)應(yīng)的時(shí)鐘節(jié)拍數(shù);
啟動(dòng)定時(shí)器。。。

4.3 注冊(cè)定時(shí)器到內(nèi)核:add_timer

頭文件

#include <linux/timer.h>

原型

void add_timer(struct timer_list *timer)

返回值

無(wú)

功能

向內(nèi)核注冊(cè)一個(gè)定時(shí)器,同步啟動(dòng)定時(shí)。本質(zhì)上把定時(shí)器結(jié)構(gòu)添加到定時(shí)鏈表

注意:同一個(gè)結(jié)構(gòu)變量在啟動(dòng)定時(shí)后,沒(méi)有超時(shí)前重復(fù)注冊(cè)沒(méi)有用的。

struct timer_list timer,
……
add_timer(&timer);
add_timer(&timer);
……

4.4 注銷(xiāo)內(nèi)核定時(shí)器:del_timer,del_timer_sync

頭文件

#include <linux/timer.h>

原型

int del_timer(struct timer_list *timer)

int del_timer_sync(struct timer_list *timer)

功能

從內(nèi)核中注銷(xiāo)一個(gè)定時(shí)器。(本質(zhì)上把定時(shí)器結(jié)構(gòu)從定時(shí)鏈表取走)

區(qū)別:  del_timer 單處理器系統(tǒng)安全刪除定時(shí)器函數(shù),del_timer_sync SMP系統(tǒng)安全刪除定時(shí)器的函數(shù)。

4.5 修改定時(shí)器定時(shí)時(shí)間:mod_timer

頭文件

#include <linux/timer.h>

原型

int mod_timer(struct timer_list *timer, unsigned long expires)

參數(shù)

timer定時(shí)器指針;

expires未來(lái)的到期時(shí)鐘節(jié)拍。

功能

修改定時(shí)器時(shí)間以及啟動(dòng)定時(shí)。

5.Linux內(nèi)核定時(shí)器示例

5.1 內(nèi)核定時(shí)器編程步驟

  • 編寫(xiě)一個(gè)定時(shí)器超時(shí)處理函數(shù)。
  • 定義struct timer_list結(jié)構(gòu)變量。
  • 初始化上一步定義的結(jié)構(gòu)變量。
  • 重新初始化到期時(shí)間,馬上啟動(dòng)定時(shí)器(注冊(cè)定時(shí)器)。
  • 如果不需要定時(shí)器,可以刪除定時(shí)器(注銷(xiāo)定時(shí)器),這一步是可選。

5.2 定時(shí)2s

#include<linux/module.h>
#include<linux/init.h>
#include<linux/timer.h>

static void timer_func(unsigned long data);

//靜態(tài)定義:定義并且初始化
DEFINE_TIMER(my_timer,timer_func,0,(unsigned long)"LIU");

//定時(shí)器超時(shí)函數(shù)
static void timer_func(unsigned long data)
{
	printk("data:%s\r\n",(char *)data);
	//啟動(dòng)新一次定時(shí),實(shí)現(xiàn)循環(huán)定時(shí)
	mod_timer(&my_timer,jiffies + 2*HZ);
}

static int __init timer_list_init(void)
{
	//重新初始化到期時(shí)間
	my_timer.expires = jiffies + 2*HZ;	//2s
	
	//馬上啟動(dòng)定時(shí)器
	printk("-----begin------\r\n");
	add_timer(&my_timer);
	printk("------end-------\r\n");
    return 0; 
}

static void __exit timer_list_exit(void)
{
	//刪除定時(shí)器
	del_timer_sync(&my_timer);
}

module_init(timer_list_init);			// 指定模塊初始化函數(shù)
module_exit(timer_list_exit);			// 指定模塊清理函數(shù)
MODULE_LICENSE("GPL");					// 聲明模塊許可證(GPL v2) 

5.3 循環(huán)定時(shí)

#include<linux/module.h>
#include<linux/init.h>
#include<linux/timer.h>

static void timer_func(unsigned long data);

//靜態(tài)定義:定義并且初始化
DEFINE_TIMER(my_timer,timer_func,0,(unsigned long)"Time out");

//定時(shí)器超時(shí)函數(shù)
static void timer_func(unsigned long data)
{
	printk("data:%s\r\n",(char *)data);
	//啟動(dòng)新一次定時(shí),實(shí)現(xiàn)循環(huán)定時(shí)
	mod_timer(&my_timer,jiffies + 2*HZ);
}

static int __init timer_list_init(void)
{
	//重新初始化到期時(shí)間
	my_timer.expires = jiffies + 2*HZ;	//2s
	
	//馬上啟動(dòng)定時(shí)器
	printk("-----begin------\r\n");
	add_timer(&my_timer);
	printk("------end-------\r\n");
    return 0; 
}

static void __exit timer_list_exit(void)
{
	//刪除定時(shí)器
	del_timer_sync(&my_timer);
}

module_init(timer_list_init);			// 指定模塊初始化函數(shù)
module_exit(timer_list_exit);			// 指定模塊清理函數(shù)
MODULE_LICENSE("GPL");					// 聲明模塊許可證(GPL v2) 

5.4 全局驅(qū)動(dòng)數(shù)據(jù)

#include <linux/module.h>
#include <linux/init.h>
#include <linux/timer.h>

//全局驅(qū)動(dòng)數(shù)據(jù)
struct drv_data{
	struct timer_list timer;
	char *data;
	u64 expires;
};
static struct drv_data gvar;

//定時(shí)器超時(shí)處理函數(shù)
static void timer_func(unsigned long data)
{
	struct drv_data *pdata = (struct drv_data *)data;
	printk("data:%s\r\n",pdata->data);
	//啟動(dòng)新一次定時(shí),實(shí)現(xiàn)循環(huán)定時(shí)
	mod_timer(&pdata->timer,jiffies + pdata->expires);
}

static int __init timer_list_init(void)
{
	//普通成員初始化
	gvar.data    = "Time out";
	gvar.expires = 2*HZ;
	
	//初始化定時(shí)器
	setup_timer(&gvar.timer,timer_func, (unsigned long)&gvar);
	
	//重新初始化到期時(shí)間
	gvar.timer.expires = jiffies + gvar.expires;	//2s
	
	//馬上啟動(dòng)定時(shí)器
	printk("-----begin------\r\n");
	add_timer(&gvar.timer);
	printk("------end-------\r\n");
    return 0; 
}

static void __exit timer_list_exit(void)
{
	//刪除定時(shí)器
	del_timer_sync(&gvar.timer);
}
module_init(timer_list_init);			// 指定模塊初始化函數(shù)
module_exit(timer_list_exit);			// 指定模塊清理函數(shù)
MODULE_LICENSE("GPL");					// 聲明模塊許可證(GPL v2) 

5.5 Linux內(nèi)核定時(shí)器應(yīng)用:實(shí)現(xiàn)按鍵消抖

5.5.1 按鍵的抖動(dòng)分析

裸機(jī)按鍵:檢測(cè),   延時(shí),  再檢測(cè),確認(rèn)按鍵

傳統(tǒng)的防抖方法用戶(hù)體驗(yàn)較差,因?yàn)檠訒r(shí)時(shí)間難以精確設(shè)定,還會(huì)占用較多的CPU資源。

早期的按鍵驅(qū)動(dòng)程序設(shè)計(jì):當(dāng)按鍵中斷觸發(fā)時(shí),直接讀取按鍵狀態(tài)來(lái)判斷按鍵動(dòng)作,這種方法容易受到機(jī)械抖動(dòng)的影響。

引入內(nèi)核定時(shí)器機(jī)制后,可以在按鍵中斷觸發(fā)時(shí)啟動(dòng)一個(gè)定時(shí)任務(wù)。待定時(shí)器超時(shí)時(shí),在其回調(diào)函數(shù)中讀取按鍵的狀態(tài)值。利用這一機(jī)制,可以每次在未超時(shí)時(shí)重新設(shè)置定時(shí)器,從而確保每次從當(dāng)前時(shí)刻重新開(kāi)始計(jì)算延時(shí),有效避免了由于抖動(dòng)帶來(lái)的誤判。這種方式不僅提高了檢測(cè)的準(zhǔn)確性,還優(yōu)化了系統(tǒng)資源的使用效率。

中斷程序啟動(dòng)定時(shí)器,每次從當(dāng)前時(shí)間開(kāi)始定時(shí)10ms,中斷程序返回

  1. 當(dāng)出現(xiàn)第一個(gè)下降沿,進(jìn)入中斷,啟動(dòng)10ms定時(shí),退出中斷
  2. 定時(shí)10ms過(guò)程中,出現(xiàn)抖動(dòng),上升沿出現(xiàn),進(jìn)入中斷,啟動(dòng)10ms定時(shí),退出中斷
  3. 定時(shí)10ms過(guò)程中,出現(xiàn)抖動(dòng),下降沿出現(xiàn),進(jìn)入中斷,啟動(dòng)10ms定時(shí),退出中斷
  4. 重復(fù)2,3步驟……直到最后一次抖動(dòng)邊沿,10ms后就有機(jī)會(huì)超時(shí)。
  5. 在超時(shí)函數(shù)讀取按鍵狀態(tài)

松開(kāi)檢測(cè)方法相同。

5.5.2 按鍵驅(qū)動(dòng)程序改進(jìn)

drv-btn.c

//增加內(nèi)核定時(shí)器功能
#include<linux/module.h>
#include<linux/fs.h>
#include<linux/miscdevice.h>
#include<asm/uaccess.h>
#include<linux/interrupt.h>
#include<linux/irq.h>
#include<linux/gpio.h>
#include<linux/slab.h>

#define LEDS_MINOR	255
#define DEVICE_NAME  "my-buttons" // 設(shè)備節(jié)點(diǎn)名稱(chēng),將在/dev目錄下創(chuàng)建 

#ifndef ARRAYSIZE
#define ARRAYSIZE(a)	(sizeof(a)/sizeof(a[0]))
#endif

//按鍵數(shù)量,在模塊初始化函數(shù)中進(jìn)行計(jì)算
static int key_size;
//按鍵緩沖區(qū),一個(gè)元素存放一個(gè)按鍵值,'1'表示按下,'0'表示松開(kāi)
//在模塊的初始化函數(shù)中分配緩沖區(qū)空間
static char *keys_buf;	

//使用面向?qū)ο笏枷朐O(shè)計(jì)按鍵,把一個(gè)按鍵信息進(jìn)行封裝
struct key_info{
	int id;					//按鍵編號(hào)
	int gpio;				//統(tǒng)一的GPIO編號(hào)
	unsigned long flags;	//觸發(fā)方式
	char *name;				//按鍵名
	int irq;				//中斷編號(hào)
	struct timer_list timer;//增加一個(gè)定時(shí)器作消抖
};

//實(shí)例化對(duì)象
static struct key_info keys[]={
	[0]={
		.id 	= 0,
		.gpio 	= 5,
		.flags 	= IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
		.name 	= "key-0",
	},
	[1]={
		.id 	= 0,
		.gpio 	= 54,
		.flags 	= IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
		.name 	= "key-1",
	},	
};

static int key_open (struct inode *pinode, struct file *pfile)
{
    printk("line:%d,%s is call\n",__LINE__,__FUNCTION__);
    return 0;    
}

loff_t key_llseek (struct file *pfile, loff_t offset, int whence)
{
    return 0;    
}

static ssize_t key_read (struct file *pfile, char __user *buf, size_t count, loff_t *offset)    
{
    int ret;
	if(count > key_size)	count = key_size;
    if(count == 0)			return 0;
	
	//準(zhǔn)備數(shù)據(jù),但是按鍵數(shù)據(jù)在中斷中實(shí)時(shí)更新,不需要在這里讀取
	//復(fù)制數(shù)據(jù)到用戶(hù)空間
	ret = copy_to_user(buf, keys_buf, count);
	if(ret){
		printk("error:copy_to_user\r\n");
		ret = -EFAULT;
		goto errot_copy_to_user;
	}
	return count;  // 返回成功讀取的字節(jié)數(shù)  
errot_copy_to_user:
	return ret;
}

int key_release (struct inode *pinode, struct file *pfile)
{
    return 0;
}

// 文件操作結(jié)構(gòu)體(關(guān)聯(lián)實(shí)現(xiàn)的操作函數(shù)) 
static const struct file_operations dev_fops = {
    .open = key_open,      // 打開(kāi)設(shè)備 
    .read = key_read,      // 讀取設(shè)備狀態(tài) 
	.owner = THIS_MODULE,
};

// 雜項(xiàng)設(shè)備定義 
static struct miscdevice key_device = {
    .name = DEVICE_NAME,	// 設(shè)備名稱(chēng)(出現(xiàn)在/dev目錄下) 
    .minor = LEDS_MINOR, 	// 次設(shè)備號(hào)(建議使用動(dòng)態(tài)分配) 
    .fops = &dev_fops,		// 關(guān)聯(lián)文件操作函數(shù)集 
};

//超時(shí)處理函數(shù)
void btn_timer(unsigned long data)
{

	int s;
	struct key_info *pdata = (struct key_info *)data;

	//檢測(cè)當(dāng)前的電平狀態(tài)
	s = !gpio_get_value(pdata->gpio);
	keys_buf[pdata->id]='0'+s;	//保存狀態(tài)
}

//按鍵中斷函數(shù)
//設(shè)置了雙邊觸發(fā),按下和松開(kāi)都會(huì)進(jìn)入這個(gè)函數(shù)
irqreturn_t btns_irq_handler(int irq,void *devid)
{
	struct key_info *pdata = (struct key_info *)devid;

	//啟動(dòng)新一次定時(shí)
	mod_timer(&pdata->timer,jiffies + msecs_to_jiffies(20));
	return IRQ_HANDLED;
}

static int __init xyd_btn_init(void)
{
    int ret,i;

	key_size = ARRAY_SIZE(keys);	//計(jì)算按鍵數(shù)量

	//分配按鍵緩沖區(qū)
	keys_buf = kzalloc(key_size,GFP_KERNEL);
	if(keys_buf == NULL)
		return -EFAULT;
	
	//循環(huán)注冊(cè)中斷
	for(i = 0;i < key_size;i++){
		keys[i].irq = gpio_to_irq(keys[i].gpio);
		if(keys[i].irq < 0)
		{
			printk("error:gpio_to_irq\r\n");
			goto error_gpio_to_irq;  
		}
		printk("irq:%d\r\n",keys[i].irq);
		
		//傳遞每個(gè)按鍵結(jié)構(gòu)變量地址,發(fā)生中斷時(shí)可以通過(guò)參數(shù)取得
		ret = request_irq(keys[i].irq, btns_irq_handler, keys[i].flags, keys[i].name, (void *)&keys[i]);
		if(ret < 0)
		{
			printk("error:request_irq\r\n");
			goto error_request_irq;  
		}

		//初始化按鍵的定時(shí)器,參數(shù)是按鍵自身的結(jié)構(gòu)內(nèi)存地址
		setup_timer(&keys[i].timer,btn_timer, (unsigned long)&keys[i]);
	}
    ret = misc_register(&key_device);
    if(ret < 0){
        printk("error:misc_register\r\n");
        goto error_misc_register;  
    }
    return 0;  								// 初始化成功 

error_misc_register:
error_request_irq:
	while(--i >= 0){
		free_irq(keys[i].irq, (void *)&keys[i]);	//注銷(xiāo)中斷
	}
	
error_gpio_to_irq:
	kfree(keys_buf);		//釋放按鍵緩沖區(qū)空間
    return ret; 
}

static void __exit key_btn_exit(void)
{
	int i = key_size;
	while(--i >= 0){
		free_irq(keys[i].irq, (void *)&keys[i]);	//注銷(xiāo)中斷
	}
	misc_deregister(&key_device);	//注銷(xiāo)雜項(xiàng)設(shè)備
	kfree(keys_buf);				//釋放按鍵緩沖區(qū)空間
}

module_init(xyd_btn_init);		  								// 指定模塊初始化函數(shù) 
module_exit(key_btn_exit);  									// 指定模塊清理函數(shù) 
MODULE_LICENSE("GPL");											// 聲明模塊許可證(GPL v2) 
MODULE_AUTHOR("LIU");    										// 模塊作者 
MODULE_DESCRIPTION("RK3399 GPIO KEY Control Driver"); 			// 模塊描述 

app.c

#include<stdio.h>              // 標(biāo)準(zhǔn)輸入輸出庫(kù)(printf, perror等)
#include<stdlib.h> 
#include<string.h> 
#include<sys/types.h>          // 系統(tǒng)數(shù)據(jù)類(lèi)型定義(如dev_t)
#include<sys/stat.h>           // 文件狀態(tài)信息(文件模式等)
#include<fcntl.h>              // 文件控制選項(xiàng)(open等)
#include<unistd.h>             // 系統(tǒng)調(diào)用封裝(lseek, read, write, sleep等)
#include<sys/ioctl.h>          // I/O控制操作(ioctl)
#include<errno.h> 

#define BTN_SIZE	1					// 按鍵數(shù)量
#define DEV_NAME 	"/dev/my-buttons"  	// 默認(rèn)設(shè)備名

int main(int argc, char **argv)
{
    int fd,ret, i;                
    const char *devname; 				// 設(shè)備路徑指針(初始化為默認(rèn)路徑)
    unsigned char pre_buf[BTN_SIZE+1],recv_buf[BTN_SIZE+1];

	memset(pre_buf,'0',BTN_SIZE);
	memset(recv_buf,'0',BTN_SIZE);
	
    if(argc == 1) 
        devname = DEV_NAME;
    else if(argc == 2)
        devname= argv[1];
    else {
        printf("Usage:%s [/dev/devname]\r\n", argv[0]);
        return 0;
    }

    fd = open(devname, O_RDWR);  			// O_RDWR:以讀寫(xiě)模式打開(kāi)
    if(fd < 0) {
        perror("open");   					// 打印系統(tǒng)錯(cuò)誤信息
        printf("fd=%d\r\n", fd);
        return -1;            				// 打開(kāi)失敗退出程序
    }
    printf("fd=%d\r\n", fd);  				// 成功打開(kāi)后輸出fd值

    while(1) {
		ret = read(fd,recv_buf,BTN_SIZE);	// 讀取按鍵數(shù)據(jù)
		if(ret < 0){
			if(errno != EAGAIN){
				perror("read");
				exit(-1);
			}else	continue;
		}

		//只在狀態(tài)發(fā)生變化時(shí)候才輸出
		for(i = 0;i < BTN_SIZE;i++){
			//分別判斷每一個(gè)按鍵狀態(tài)是否發(fā)生變化
			if(recv_buf[i] != pre_buf[i]){
				//更新當(dāng)前狀態(tài)為上一次狀態(tài)
				pre_buf[i] = recv_buf[i];

				//判斷這次變化是按下還是松開(kāi)
				if(pre_buf[i] == '1')	printf("KEY%d is press!\r\n",i+1);
				else					printf("KEY%d is up!\r\n",i+1);
			}
		}
    }    
    return 0;
}

現(xiàn)象

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 超詳細(xì)的Spring Boot入門(mén)筆記(總結(jié))

    超詳細(xì)的Spring Boot入門(mén)筆記(總結(jié))

    本篇文章主要介紹了超詳細(xì)的Spring Boot入門(mén)筆記(總結(jié)),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-11-11
  • Java中Word變量進(jìn)行添加、統(tǒng)計(jì)、獲取與刪除操作詳解

    Java中Word變量進(jìn)行添加、統(tǒng)計(jì)、獲取與刪除操作詳解

    本文將介紹如何利用 Java 語(yǔ)言,借助 Spire.Doc for Java 庫(kù),在不依賴(lài) Microsoft Word 環(huán)境的情況下,對(duì) Word 文檔中的變量進(jìn)行添加、統(tǒng)計(jì)、檢索和刪除操作,希望對(duì)大家有所幫助
    2026-05-05
  • java阿拉伯?dāng)?shù)字轉(zhuǎn)中文數(shù)字

    java阿拉伯?dāng)?shù)字轉(zhuǎn)中文數(shù)字

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)阿拉伯?dāng)?shù)字轉(zhuǎn)換為中文數(shù)字,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-04-04
  • IDEA2020.1構(gòu)建Spring5.2.x源碼的方法

    IDEA2020.1構(gòu)建Spring5.2.x源碼的方法

    這篇文章主要介紹了IDEA2020.1構(gòu)建Spring5.2.x源碼的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • SpringBoot整合Swagger框架過(guò)程解析

    SpringBoot整合Swagger框架過(guò)程解析

    這篇文章主要介紹了SpringBoot整合Swagger框架過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • SpringBoot整合Redis的步驟

    SpringBoot整合Redis的步驟

    這篇文章主要介紹了SpringBoot整合Redis的步驟,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下
    2020-11-11
  • MyBatis中resultType和parameterType和resultMap使用總結(jié)

    MyBatis中resultType和parameterType和resultMap使用總結(jié)

    這篇文章主要介紹了MyBatis中resultType和parameterType和resultMap使用總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • springboot-2.3.x最新版源碼閱讀環(huán)境搭建(基于gradle構(gòu)建)

    springboot-2.3.x最新版源碼閱讀環(huán)境搭建(基于gradle構(gòu)建)

    這篇文章主要介紹了springboot-2.3.x最新版源碼閱讀環(huán)境搭建(基于gradle構(gòu)建),需要的朋友可以參考下
    2020-08-08
  • Spring @Retryable注解輕松搞定循環(huán)重試功能

    Spring @Retryable注解輕松搞定循環(huán)重試功能

    spring系列的spring-retry是另一個(gè)實(shí)用程序模塊,可以幫助我們以標(biāo)準(zhǔn)方式處理任何特定操作的重試。在spring-retry中,所有配置都是基于簡(jiǎn)單注釋的。本文主要介紹了Spring@Retryable注解如何輕松搞定循環(huán)重試功能,有需要的朋友可以參考一下
    2023-04-04
  • Java操作redis設(shè)置第二天凌晨過(guò)期的解決方案

    Java操作redis設(shè)置第二天凌晨過(guò)期的解決方案

    這篇文章主要介紹了Java操作redis設(shè)置第二天凌晨過(guò)期的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01

最新評(píng)論

夏津县| 循化| 新田县| 张北县| 温宿县| 囊谦县| 蓬安县| 潮安县| 甘泉县| 龙海市| 襄城县| 克东县| 分宜县| 泾源县| 长岛县| 密山市| 册亨县| 读书| 湄潭县| 绿春县| 新宁县| 布尔津县| 新昌县| 乌鲁木齐县| 永泰县| 临安市| 文昌市| 固镇县| 阿拉尔市| 轮台县| 来安县| 宣威市| 土默特右旗| 绥芬河市| 高陵县| 阜南县| 天峨县| 潼关县| 宜兰县| 武强县| 梁山县|