linux内核信号量和互斥锁使用
信号量概念Linux 内核的信号量在概念和原理上与用户态的 System V 的 IPC 机制信号量是一样的但是它绝不可能在内核之外使用因此它与 System V 的 IPC 机制信号量毫不相干。信号量在创建时需要设置一个初始值表示同时可以有几个任务可以访问该信号量保护的共享资源初始值为 1 就变成互斥锁Mutex即同时只能有一个任务可以访问信号量保护的共享资源。一个任务要想访问共享资源首先必须得到信号量获取信号量的操作将把信号量的值减 1若当前信号量的值为负数表明无法获得信号量该任务必须挂起在该信号量的等待队列等待该信号量可用若当前信号量的值为非负数表示可以获得信号量因而可以立刻访问被该信号量保护的共享资源。当任务访问完被信号量保护的共享资源后必须释放信号量释放信号量通过把信号量的值加 1 实现如果信号量的值为非正数表明有任务等待当前信号量因此它也唤醒所有等待该信号量的任务。内核信号量核心结构内核中使用 struct semaphore 结构来描述一个信号量结构定义如下struct semaphore { raw_spinlock_t lock; unsigned int count; //信号值只要这个值为正数则信号可用 一般情况设置 0 或 1。 struct list_head wait_list; };信号量相关 APIDEFINE_SEMAPHORE (name)宏原型#define DEFINE_SEMAPHORE(name) \struct semaphore name __SEMAPHORE_INITIALIZER(name, 1)宏功能该宏声明一个信号量 name 并初始化它的值为 1即声明一个互斥锁宏参数name 要定义的信号量变量名所在头文件include\linux\semaphore.h宏定义文件include\linux\semaphore.h备注Linux3.5 内核出现 在 linux 2.6 中名字为 DECLARE_MUTEX(name)void sema_init(struct semaphore *sem, int val)宏函数 原型void sema_init(struct semaphore *sem, int val)宏功能该函数用于初始化一个互斥锁即它把信号量 sem 的值设置为 1。宏参数sem 要初始化的信号量的指针所在头文件include\linux\semaphore.h宏定义文件include\linux\semaphore.h备注void sema_init (struct semaphore *sem, int val);宏原型void sema_init (struct semaphore *sem, int val);宏功能初始化设置信号量的初值它设置信号量 sem 的值为 val宏参数sem 要初始化的信号量的指针val: 信号量的值所在头文件include\linux\semaphore.h宏定义文件include\linux\semaphore.h定义、初始化信号量相关 API:这是一个静态定义方式。 定义一个名字为 name,信号量值为 1 的信号量结构变量。示例struct semaphore sem;sema_init(sem, 1);以上两行等效DEFINE_SEMAPHORE(sem);void down(struct semaphore *sem)函数原型void down(struct semaphore * sem);函数功能用于获得信号量 sem它会导致睡眠因此不能在中断上下文包括 IRQ 上下文和 softirq 上下文使用该函数。该函数将把 sem 的值减 1如果信号量 sem 的值非负就直接返回否则调用者将被挂起直到别的任务释放该信号量才能继续运行。函数参数sem 要初始化获取的信号量的指针函数返回值无所在头文件include\linux\semaphore.h函数定义文件kernel\semaphore.cint down_timeout(struct semaphore *sem, long jiffies);sem 信号量结构指针jiffies 要设置超时时间单位是时钟节拍。阻塞地请求一个信号量,如果信号量大于 0 则可以马上返回 否则休眠直到有其他进程释放信号量把信号量的 count 修改为大于 0 的值 或超时时间到。这个函数效果和 down 函数很像它也是不可中断的休眠。int down_interruptible(struct semaphore * sem);函数原型int down_interruptible(struct semaphore * sem);函数功能该函数功能与 down 类似不同之处为 down 不会被信号signal打断但 down_interruptible能被信号打断因此该函数有返回值来区分是正常返回还是被信号中断如果返回 0表示获得信号量正常返回如果被信号打断返回-EINTR。函数参数sem 要获取的信号量的指针函数返回值0得到信号量正常返回 负数被信号中断返回所在头文件include\linux\semaphore.h函数定义文件kernel\semaphore.cint down_trylock(struct semaphore * sem);函数原型int down_trylock(struct semaphore * sem);函数功能该函数试着获得信号量 sem如果能够立刻获得它就获得该信号量并返回 0否则表示不能获得信号量 sem返回值为非 0 值。因此它不会导致调用者睡眠可以在中断上下文使用。函数参数sem 要获取的信号量的指针函数返回值0得到信号量正常返回 非 0得不到信号量所在头文件include\linux\semaphore.h函数定义文件kernel\semaphore.cvoid up(struct semaphore * sem);函数原型void up(struct semaphore * sem);函数功能该函数释放信号量 sem即把 sem 的值加 1如果 sem 的值为非正数表明有任务等待该信号量因此唤醒这些等待者。函数参数sem 要初释放的信号量的指针函数返回值无头文件include\linux\semaphore.h函数定义文件kernel\semaphore.c虽然信号量可以设置为大于 1 的值但是信号量在绝大部分情况下作为互斥锁使用。简单信号量使用例子实现设备只能被一个进程打开#include linux/module.h /* Needed by all modules */ #include linux/init.h /* Needed for the module-macros */ #include linux/fs.h #include linux/miscdevice.h #include asm/atomic.h #define LEDS_MAJOR 255 #define DEVICE_NAME miscdev_semaphore DECLARE_MUTEX(lock); //定义一个互斥信号量并初始化 1; static int first_miscdev_open(struct inode *pinode, struct file *pfile) { printk (KERN_EMERG Linux miscdevice:%s is call\r\n,__FUNCTION__); /* 获取信号量 */ if (!down_trylock(lock)) return 0; else return -EBUSY; } int first_miscdev_release (struct inode *inode, struct file *file) { printk (KERN_EMERG Linux miscdevice:%s is call\r\n,__FUNCTION__); up(lock); //释放信号量 return 0; } static struct file_operations dev_fops { .owner THIS_MODULE, .open first_miscdev_open, .release first_miscdev_release, }; static struct miscdevice misc { .minor LEDS_MAJOR, .name DEVICE_NAME, .fops dev_fops, }; /* 模块装载执行函数 */ static int __init first_miscdev_init(void) { int ret; ret misc_register(misc); //注册混杂设备 if(ret 0) printk (KERN_EMERG DEVICE_NAME\t err\r\n); printk (KERN_EMERG DEVICE_NAME\tinitialized\n); return ret; } /* 模块卸载执行函数 */ static void __exit first_miscdev_exit(void) { misc_deregister(misc); printk(KERN_EMERG Goodbye,cruel world!, priority 0\n); } module_init(first_miscdev_init); module_exit(first_miscdev_exit); MODULE_LICENSE(GPL); MODULE_AUTHOR(XYD); MODULE_DESCRIPTION(This the samlpe drv_test);互斥信号量互斥信号量概念互斥锁主要用于实现内核中的互斥访问功能。内核互斥锁是在原子 API 之上实现的但这对于内核用户是不可见的。 在大部分场合中对共享资源的访问都是使用独占方式 在这种情况下 提供专门的互斥接口给编程者使用。 对它的访问必须遵循一些规则同一时间只能有一个任务持有互斥锁而且只有这个任务可以对互斥锁进行解锁。互斥锁不能进行递归锁定或解锁。一个互斥锁对象必须通过其 API 初始化而不能使用 memset 或复制初始化。一个任务在持有互斥锁的时候是不能结束的。互斥锁所使用的内存区域是不能被释放的。使用中的互斥锁是不能被重新初始化的。并且互斥锁不能用于中断上下文。但是互斥锁比当前的内核信号量选项更快并且更加紧凑因此如果它们满足您的需求那么它们将是您明智的选择。内核信号量核心结构内核中使用 struct mutex 结构来描述一个信号量结构定义如下struct mutex { /* 1: unlocked, 0: locked, negative: locked, possible waiters */ atomic_t count; spinlock_t wait_lock; struct list_head wait_list; #if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_SMP) struct task_struct *owner; #endif #ifdef CONFIG_DEBUG_MUTEXES const char *name; void *magic; #endif #ifdef CONFIG_DEBUG_LOCK_ALLOC struct lockdep_map dep_map; #endif };关键成员说明atomic_t count指示互斥锁的状态1--没有上锁可以获得0--被锁定不能获得负数--被锁定且可能在该锁上有等待进程初始化时为没有上锁状态。spinlock_t wait_lock等待获取互斥锁中使用的自旋锁。在获取互斥锁的过程中操作会在自旋锁的保护中进行。初始化为为锁定 用户一般无需关心。struct list_head wait_list等待互斥锁的进程队列 用户无需关心。互斥信号量相关 APIDEFINE_MUTEX(mutexname)宏原型#define DEFINE_MUTEX(mutexname) \struct mutex mutexname __MUTEX_INITIALIZER(mutexname)宏功能该宏声明一个互斥信号量 name 并初始化它宏参数name 要定义的互斥信号量变量名所在头文件include\linux\mutex.h备注linux3.5出现mutex_init(mutex)宏原型# define mutex_init(mutex) \do { \static struct lock_class_key __key; \__mutex_init((mutex), #mutex, __key); \} while (0)宏功能该宏初始化一个已经定义的互斥信号量 metex 传递的是指针宏参数mutex 初始化的的互斥信号量指针所在头文件include\linux\mutex.h宏定义文件include\linux\mutex.hint mutex_is_locked(struct mutex *lock)宏原型int mutex_is_locked(struct mutex *lock)宏功能该函数检测互斥锁是否已经被锁定宏参数lock 互斥锁变量是指针返回值1 已经锁定 0 没有锁定所在头文件include\linux\mutex.hmutex_lock(lock) 或 void mutex_lock(struct mutex *lock);宏函数 原型mutex_lock(lock)或void mutex_lock(struct mutex *lock);宏功能该宏函数 获取互斥锁是否 如没有得到会休眠直接得到为止宏参数lock 互斥锁变量是指针返回值无所在头文件include\linux\mutex.h宏定义文件include\linux\mutex.h备注根据内核配置不同该功能有有宏版本和函数版本mutex_lock_interruptible(lock) 或 int mutex_lock_interruptible(struct mutex *lock);宏原型#define mutex_lock_interruptible(lock) mutex_lock_interruptible_nested(lock, 0)或int __must_check mutex_lock_interruptible(struct mutex *lock);宏功能该宏函数获取互斥锁是否 如没有得到会休眠直接得到为止 但是可以被信号中断宏参数lock 互斥锁变量是指针返回值成功获得锁返回 0 被信号中断返回-EINIR所在头文件include\linux\mutex.h宏定义文件include\linux\mutex.h备注根据内核配置不同该功能有有宏版本和函数版本int mutex_trylock(struct mutex *lock);宏原型int mutex_trylock(struct mutex *lock);宏功能该函数是获取互斥锁 如没有得到不会休眠马上返回宏参数lock 互斥锁变量是指针返回值无所在头文件include\linux\mutex.h宏定义文件include\linux\mutex.c备注根据内核配置不同该功能有有宏版本和函数版本void mutex_unlock(struct mutex *lock);宏原型void mutex_unlock(struct mutex *lock);宏功能该函数是释放互斥锁宏参数lock 互斥锁变量是指针返回值无所在头文件include\linux\mutex.h宏定义文件include\linux\mutex.c互斥锁应用例子/* chardev.c */ #include linux/module.h /* Needed by all modules */ #include linux/init.h /* Needed for the module-macros */ #include linux/fs.h #include linux/cdev.h #include linux/device.h /* 自动创建设备文件 */ #include linux/miscdevice.h #include asm/io.h /*ioremap*/ #include asm/uaccess.h /*copy_from_user ,copy_to_user*/ #include linux/atomic.h #include linux/mutex.h #include linux/gpio.h #include mach/gpio.h #include plat/gpio-cfg.h /* s3c_gpio_cfgpin S3C_GPIO_OUTPUT */ static struct cdev *pcdev; static struct device *this_device NULL; static struct class *leds_class NULL; /* 是否开启 gpio_request 函数功能 */ #define GPIO_REQUEST 1 //0 :关,非0 :开 static int led_gpios[] { EXYNOS4X12_GPM4(0), EXYNOS4X12_GPM4(1), EXYNOS4X12_GPM4(2), EXYNOS4X12_GPM4(3), }; #define LED_NUM ARRAY_SIZE(led_gpios) #define DEV_NAME myleds unsigned int major 0; //主设备号 unsigned int minor 0; //次设备号 unsigned int devnr 0; //设备号 char *chrdev_name DEV_NAME; //设备名 module_param(major, int, S_IRUGO | S_IWUSR); module_param(minor, int, S_IRUGO | S_IWUSR); module_param(chrdev_name, charp, S_IRUGO | S_IWUSR); struct mutex lock; //打开设备时候执行的程序 static int chrdev_open(struct inode *pinode, struct file *pfile) { mutex_lock(lock); printk(KERN_EMERG line:%d,%s is call\n, __LINE__, __FUNCTION__); return 0; } //关闭设备时执行的程序 static int chrdev_release(struct inode *pinode, struct file *pfile) { mutex_unlock(lock); printk(KERN_EMERG line:%d,%s is call\n, __LINE__, __FUNCTION__); return 0; } //读接口函数 static ssize_t chrdev_read ( struct file *file, char __user *buf, size_t count, loff_t * f_pos ) { char led_buffer[4] {2, 2, 2, 2}; int i 0; // printk ( KERN_EMERG line:%d,%s is call\n, __LINE__, __FUNCTION__ ); /* count 0 ,则返回0不是错误 */ if ( !count ) { return 0; } /* 当前已经到文件末尾不能再写返回0,*/ if ( count LED_NUM ) { count LED_NUM; } /* 准备数据0表示灭1表示亮 */ for (i 0; i LED_NUM; i) { led_buffer[i] !gpio_get_value(led_gpios[i]); } if ( copy_to_user ( buf, led_buffer[0], count ) ) { return -EFAULT; } return count; } //写接口函数 static ssize_t chrdev_write(struct file *pfile, const char __user *user_buf, size_t count, loff_t *off) { int ret 0; char buf[LED_NUM] {0}; int i 0; // printk(KERN_EMERG line:%d,%s is call\n, __LINE__, __FUNCTION__); //应用程序传递count0下来并不是错误应该返回0 if(count 0) { return 0; } //因为板子只有4个灯所以防止用户程序恶意破坏系统。 if(count LED_NUM) { count LED_NUM; } //把用户空间传递下来的数据复制到内核空间的buf数组中 ret copy_from_user(buf, user_buf, count); //返回成功是0其他是失败 if(ret) { //如果复制失败返回-1; return -EFAULT; } for(i 0; i count; i) { if(buf[i] 1) // GPM4DAT ~(1 (0 i));/* 亮 */ { gpio_set_value(led_gpios[i], 0); } else if(buf[i] 0) // rGPM4DAT | (1 (0 i));/* 灭 */ { gpio_set_value(led_gpios[i], 1); } } count 1; return count; } //文件操作方法 static const struct file_operations chrdev_fops { .read chrdev_read, .write chrdev_write, .release chrdev_release, .open chrdev_open, }; static int __init chrdev_init(void) { int ret 0; int i; /* IO口配置代码 */ for (i 0; i LED_NUM; i) { #if GPIO_REQUEST ret gpio_request(led_gpios[i], LED); if (ret) { printk(%s: request GPIO %d for LED failed, ret %d\n, chrdev_name, led_gpios[i], ret); goto gpio_request_err; } #endif //s3c_gpio_cfgpin(led_gpios[i], S3C_GPIO_OUTPUT); //gpio_set_value(led_gpios[i], 1); //gpio_direction_output等效于上面两条语句, gpio_direction_output(led_gpios[i], 1); } //分配cdev核心结构; pcdev cdev_alloc(); if (pcdev NULL) { ret -ENOMEM; printk(KERN_EMERGcdev_alloc_err error\n); goto cdev_alloc_err; } //如果主设备号是0,则动态分配设备号 if(!major) { ret alloc_chrdev_region(devnr, minor, 1, chrdev_name); if(ret 0) { printk(KERN_EMERGalloc_chrdev_region error\n); goto devnr_requst_err; } } else { //合成设备号 devnr MKDEV(major, minor); //静态注册设备号 ret register_chrdev_region(devnr, 1, chrdev_name); if(ret ! 0) { printk(KERN_EMERGregister_chrdev_region error\n); goto devnr_requst_err; } } //cdev结构体初始化 cdev_init(pcdev, chrdev_fops); //注册字符设备 ret cdev_add(pcdev, devnr, 1); if ( ret 0) { printk(KERN_EMERGcdev_add error\n); goto cdev_add_err; } //输出字符设备主设备号和次设备号 printk(KERN_EMERG name:%s,major:%d,minor:%d\n, chrdev_name, MAJOR(devnr), MINOR(devnr)); //创建一个类 leds_class class_create(THIS_MODULE, leds_class); if ( IS_ERR(leds_class) ) { ret PTR_ERR(leds_class); printk(KERN_EMERGclass_create error\n); goto class_create_err; } //创建一个设备 this_device device_create(leds_class, NULL, devnr, NULL, %s, chrdev_name); if ( IS_ERR(this_device) ) { ret PTR_ERR(this_device); printk(KERN_EMERGthis_device error\n); goto device_create_err; } mutex_init(lock); return 0; device_create_err: class_destroy(leds_class); class_create_err: unregister_chrdev(major, chrdev_name); cdev_add_err: devnr_requst_err: if (pcdev) { cdev_del(pcdev); } unregister_chrdev_region(devnr, 1); cdev_alloc_err: #if GPIO_REQUEST gpio_request_err: /* gpio 反向释放 */ for ( --i ; i 0 ; i-- ) { gpio_free(led_gpios[i]); } #endif return ret; } static void __exit chrdev_exit(void) { int i 0; device_destroy(leds_class, devnr); class_destroy(leds_class); /* gpio 反向释放 */ for ( ; i 4 ; i) { gpio_free(led_gpios[i]); } cdev_del(pcdev); unregister_chrdev_region(devnr, 1); printk(KERN_EMERG Goodbye,chrdev\n); } module_init(chrdev_init); module_exit(chrdev_exit); MODULE_LICENSE(Dual BSD/GPL); MODULE_AUTHOR(learn); //optional MODULE_DESCRIPTION(STUDY_MODULE); //optional

相关新闻

GitHub 2FA 不是只填六位码:TOTP、Passkey、恢复方式与 PAT

GitHub 2FA 不是只填六位码:TOTP、Passkey、恢复方式与 PAT

GitHub 的账户安全需要拆成三层:网页登录的第二因素、账户恢复方式,以及 Git/API 使用的开发凭据。只配置验证器代码,不能自动解决恢复码、Passkey、Personal Access Token 或 SSH Key 的管理问题。 GitHub 2FA 的组成 GitHub 官方当前提供…

2026/7/28 18:48:17 阅读更多 →
PHP:数组截取与合并函数、数组拆分与连接函数:

PHP:数组截取与合并函数、数组拆分与连接函数:

数组截取与合并函数: 1.array_slice($arr,2,3); 从下标为2开始&#xff0c;截取3个值 数组截取.** <?php $arrarray(title1>linux,title2>java,title3>php,title4>js,title5>shell,title6>python,title7>ruby,title8>c, );$arr2array_slice($arr,…

2026/7/28 18:48:17 阅读更多 →
SQLite Viewer 终极指南:如何在线免费查看和导出SQLite数据库

SQLite Viewer 终极指南:如何在线免费查看和导出SQLite数据库

SQLite Viewer 终极指南&#xff1a;如何在线免费查看和导出SQLite数据库 【免费下载链接】sqlite-viewer View SQLite file online 项目地址: https://gitcode.com/gh_mirrors/sq/sqlite-viewer SQLite Viewer 是一款功能强大的在线 SQLite 文件查看器&#xff0c;让您…

2026/7/28 18:48:17 阅读更多 →

最新新闻

摆脱环境配置难题!OpenClaw 小龙虾 Windows 系统搭建全流程(含安装包)

摆脱环境配置难题!OpenClaw 小龙虾 Windows 系统搭建全流程(含安装包)

&#x1f4d8;OpenClaw v2.7.9 Windows 一键部署指南&#xff5c;本地 AI 智能体零基础搭建教程 前言✨ 当下各类 AI 工具层出不穷&#xff0c;但多数产品仅支持文字对话&#xff0c;很难直接操控电脑完成各类重复工作。OpenClaw&#xff0c;爱好者俗称小龙虾&#xff0c;作为…

2026/7/28 19:00:21 阅读更多 →
AI 办公自动化实践:Windows 平台部署 OpenClaw,打造桌面自动化助手(含安装包)

AI 办公自动化实践:Windows 平台部署 OpenClaw,打造桌面自动化助手(含安装包)

Windows 本地 AI 智能体 OpenClaw 部署教程&#xff5c;零代码搭建自动化办公助手&#xff0c;新手也能一次成功 ✨核心亮点&#xff1a;全程可视化操作&#xff5c;无需手动配置环境&#xff5c;内置全套运行依赖&#xff5c;支持本地离线运行&#xff5c;配备 28 万 Tokens …

2026/7/28 19:00:21 阅读更多 →
外卖CPS管理系统排名,卡券到期自动退款逻辑开发

外卖CPS管理系统排名,卡券到期自动退款逻辑开发

外卖CPS管理系统排名&#xff0c;卡券到期自动退款逻辑开发外卖CPS管理系统的核心资产是各类付费折扣卡、会员券、专属补贴券&#xff0c;用户付费购买的卡券存在固定使用有效期。在实际运营场景中&#xff0c;大量用户购买折扣卡后未及时核销使用&#xff0c;卡券到期后会产生…

2026/7/28 19:00:21 阅读更多 →
资本积累的负反馈循环与文明再生产的结构性危机

资本积累的负反馈循环与文明再生产的结构性危机

资本积累的负反馈循环与文明再生产的结构性危机 ——基于马克思主义政治经济学与系统动力学的综合性研究 摘要 本文以马克思主义政治经济学为方法论基础&#xff0c;整合列宁帝国主义理论、系统动力学负反馈循环理论、历史社会学制度分析方法及卡尔波兰尼的“双重运动”理论框架…

2026/7/28 19:00:21 阅读更多 →
5分钟快速上手:基于深度学习AI的中国象棋智能辅助工具完整指南

5分钟快速上手:基于深度学习AI的中国象棋智能辅助工具完整指南

5分钟快速上手&#xff1a;基于深度学习AI的中国象棋智能辅助工具完整指南 【免费下载链接】VinXiangQi Xiangqi syncing tool based on Yolov5 / 基于Yolov5的中国象棋连线工具 项目地址: https://gitcode.com/gh_mirrors/vi/VinXiangQi 还在为在线下棋时无法获得专业分…

2026/7/28 19:00:21 阅读更多 →
随记:springboot+spring-security

随记:springboot+spring-security

该文章为备忘&#xff0c;个人用package com.szq.le.config;import java.util.ArrayList; import java.util.Collection; import java.util.List;import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.autoconfigure.SpringBootApplication; imp…

2026/7/28 18:59:20 阅读更多 →

日新闻

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿!3步让你的暗影精灵笔记本重获新生

告别臃肿&#xff01;3步让你的暗影精灵笔记本重获新生 【免费下载链接】OmenSuperHub Control Omen laptop performance, fan speeds, and keyboard lighting, and unlock power limits. 项目地址: https://gitcode.com/gh_mirrors/om/OmenSuperHub 你是否也曾为官方Om…

2026/7/28 0:00:43 阅读更多 →
RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

RAG必踩坑!财报法规检索不准?这款开源工具让答案浮出水面,准确率飙升98.7%!

做 RAG 的人应该都踩过这个致命的坑&#xff1a;把几百页的财报、法规、技术手册扔给向量库&#xff0c;问一个具体问题&#xff0c;搜出来的全是沾边但没用的内容 —— 关键信息要么被硬切块拆碎了&#xff0c;要么藏在几十条结果的最下面。语义相似≠真正相关&#xff0c;这个…

2026/7/28 0:00:43 阅读更多 →
抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

抖音视频文案提取工具全指南:免费2026版、手机App、在线工具一网打尽

2026年做短视频运营&#xff0c;从抖音上扒文案早就不是偷偷抄笔记的事了。我刚开始做内容的时候&#xff0c;每天刷半小时抖音&#xff0c;手动把爆款视频的口播敲进备忘录&#xff0c;一条2分钟的视频得花十来分钟&#xff0c;碰到语速快的还要反复回听。后来试了一圈工具&am…

2026/7/28 0:00:43 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档&#xff0c;可以直接使用&#xff01;系统支持图片、视频、摄像头等多种方式检测裂缝&#xff0c;功能强大实用。 1数据集6000张 8各类别

2026/7/28 12:04:22 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像&#xff01; pubg绝地求生目标检测数据集 1分类&#xff1a;e_body&#xff0c;14905个标签&#xff0c;txt格式 共计14244张图&#xff0c;99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/28 8:29:16 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别&#xff1a; allies enemy tag图片总量&#xff1a;7247张训练集&#xff1a;5139张验证集&#xff1a;1425张测试集&#xff1a;683张标注状态&#xff1a;全部已标注&#xff0c;即拿即用数据格式&#xff1a;支持YOLO格式及其他格式&#…

2026/7/28 5:03:42 阅读更多 →

月新闻