惠州住房和建设局网站/软文范例100字

惠州住房和建设局网站,软文范例100字,怎样建设一个网站,濮阳做网站的公司Linux驱动开发-①中断②阻塞、非阻塞IO和异步通知 一,中断1.中断的流程2.上半部和下半部2.1上半部2.2下半部2.2.1 tasklet2.2.2 工作队列 3.按键延时消抖中断程序 二,阻塞和非阻塞IO和异步通知1.阻塞IO1.1 常见结构11.2 常见结构2 2.非阻塞IO2.1 驱动结构…

Linux驱动开发-①中断②阻塞、非阻塞IO和异步通知

  • 一,中断
    • 1.中断的流程
    • 2.上半部和下半部
      • 2.1上半部
      • 2.2下半部
        • 2.2.1 tasklet
        • 2.2.2 工作队列
    • 3.按键延时消抖中断程序
  • 二,阻塞和非阻塞IO和异步通知
    • 1.阻塞IO
      • 1.1 常见结构1
      • 1.2 常见结构2
    • 2.非阻塞IO
      • 2.1 驱动结构
      • 2.2 select 应用程序
      • 2.3 poll 应用程序
    • 3.异步通知

一,中断

1.中断的流程

  ①获取中断号以及中断名②申请中断③释放中断

/*中断结构体*/
struct irq_key{int key_gpio;     //io编号int irq;  //中断号unsigned char gpio_name[6];//设置中断名irqreturn_t (*handler)(int, void *);
};static irqreturn_t key_irq_hander(int irq, void *dev_id)//中断处理函数,遇到上升沿或者下降沿触发定时器{..............}/*中断设置*/key.irq_struct.irq = gpio_to_irq(key.irq_struct.key_gpio);//获取中断号key.irq_struct.handler = key_irq_hander;//中断函数表注册,即中断函数ret = request_irq(key.irq_struct.irq,key.irq_struct.handler,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, key.irq_struct.gpio_name, &key);/*释放中断*/free_irq(key.irq_struct.irq, &key);

2.上半部和下半部

2.1上半部

  上半部执行的是紧急的,不可延迟的任务。当中断上半部执行时,当前CPU上的其他程序包括用户空间程序和内核线程都会暂时阻塞,直到中断处理完成
  不可抢占:在中断上下文中,当前 CPU 会禁用抢占,直到中断处理完成。不能睡眠:中断上下文中不能调用可能睡眠的函数(如 kmalloc(GFP_KERNEL)、mutex_lock 等)。高优先级:中断处理程序的优先级高于普通进程和内核线程。

2.2下半部

  下半部处理非紧急的,耗时的任务,将复杂的任务推迟到合适的时机,避免阻塞中断上半部。可以运行在进程上下文中,睡眠或者调用睡眠的函数,能被其他中断或者是任务抢占。用的tasklet(软中断,依旧不能睡眠,优先级依旧高,适用于网络数据包处理,块设备处理)和工作队列(可以睡眠,比较耗时的任务,比如访问系统文件,分配内存)。

2.2.1 tasklet

  tasklet跟工作队列实际使用差不多,tasklet他的处理函数传递参数,工作队列不传递。这个在初始化的时候也能发现,tasklet函数初始化需要三个参数,包括传递的设备参数结构体,工作队列初始化只需要两个参数。

struct tasklet_struct tasklet;
/*tasklet*/
static void tasklet_func(unsigned long data)//中断下半部tasklet函数
{
........
}
static irqreturn_t key_irq_hander(int irq, void *dev_id)//中断处理函数
{struct key_dev *key_irq = (struct key_dev*)dev_id;tasklet_schedule(&key_irq->irq_struct.tasklet);//调用中断下半部return IRQ_HANDLED;
}/*初始化*/	
tasklet_init(&key.irq_struct.tasklet,tasklet_func, (unsigned long)&key);
2.2.2 工作队列
 struct work_struct testwork; //工作队列
/*工作队列*/
void testwork_func_t(struct work_struct *work)//中断下半部
{
........
}
static irqreturn_t key_irq_hander(int irq, void *dev_id)//中断处理函数
{struct key_dev *key_irq = (struct key_dev*)dev_id;schedule_work(&key_irq->irq_struct.testwork);//工作队列return IRQ_HANDLED;
}/*初始化*/	
INIT_WORK(&key.irq_struct.testwork,testwork_func_t);

3.按键延时消抖中断程序

#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/cdev.h>
#include <linux/kdev_t.h>
#include <linux/device.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/fs.h>  
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/ioctl.h>
#include <linux/irq.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <linux/interrupt.h>
#include <linux/string.h>
#define KEY_NAME "key_irq"
#define KEY_EN_VALUE  0X01
#define KEY_NO_VALUE  0X00
static int key_pan=0;
/*中断结构体*/
struct irq_key{int key_gpio;     //io编号int irq;  //中断号unsigned char value; //按键值unsigned char gpio_name[6];//设置按键名irqreturn_t (*handler)(int, void *);struct tasklet_struct tasklet;//taskletstruct work_struct testwork; //工作队列};
struct key_dev{struct class *class;struct device *device;struct device_node *nd;struct cdev cdev;dev_t key_hao;int major;  //主设备号int minor;  //次设备号struct irq_key irq_struct;/*中断结构体*/int timer_period;//定时器周期  利用原子操作保护atomic_t lock_yuan;//原子操作struct timer_list timer;//定义定时器  
};
struct key_dev key;
static int pgkey_open(struct inode *innode,struct file *filp)
{filp->private_data = &key;//将key结构体数据设为私有数据return 0;
}static int pgkey_release(struct inode *innode,struct file *filp)
{return 0;
}
static ssize_t key_read(struct file *filp,  char __user *buf, size_t count, loff_t *ppos)
{static int key_value = 0,ret = 0;struct key_dev *key_read =(struct key_dev *)filp->private_data;key_value = key_read->irq_struct.value; if(key_pan)//按下{ret = __copy_to_user(buf, &key_value, sizeof(key_value));if(ret<0){printk("key value read error!\r\n");return -1;}        }key_pan = 0;return 0;}
static struct file_operations pgkey_fops={.owner=THIS_MODULE,.open=pgkey_open,.read=key_read,.release=pgkey_release,};
static void key_timer_function(unsigned long arg)//定时结束后会执行第操作,
{static int ret = 0;struct key_dev *key_t = (struct key_dev*)arg;ret = gpio_get_value(key_t->irq_struct.key_gpio);if(ret==0){printk("KEY PUSH\r\n");key_t->irq_struct.value = KEY_EN_VALUE;key_pan = 1;}else {printk("KEY PULL\r\n");key_t->irq_struct.value = KEY_NO_VALUE;}
}/*工作对列*/
void testwork_func_t(struct work_struct *work)//工作队列和tasklet函数使用不同,ta这个函数通过本身传递参数,工作队列不传参数进来.
{// struct key_dev *key_work = (struct key_dev*)work;key.timer.data = (unsigned long)&key;mod_timer(&key.timer, jiffies+msecs_to_jiffies(15));//添加定时器,并且设置定时器时间printk("key_work !!!\r\n");
}// /*tasklet*/
// static void tasklet_func(unsigned long data)//中断下半部tasklet函数
// {
//     struct key_dev *key_task = (struct key_dev*)data;
//     key_task->timer.data = data;
//     mod_timer(&key_task->timer, jiffies+msecs_to_jiffies(15));//添加定时器,并且设置定时器时间
//     printk("tasklet !!!\r\n");
// }
static irqreturn_t key_irq_hander(int irq, void *dev_id)//中断处理函数,遇到上升沿或者下降沿触发定时器
{struct key_dev *key_irq = (struct key_dev*)dev_id;schedule_work(&key_irq->irq_struct.testwork);//工作队列// tasklet_schedule(&key_irq->irq_struct.tasklet);//调用中断下半部函数// key_irq->timer.data = (unsigned long)dev_id;// mod_timer(&key_irq->timer, jiffies+msecs_to_jiffies(15));//添加定时器,并且设置定时器时间return IRQ_HANDLED;
}static void gpio_init(void)
{int ret =0;// atomic_set(&key.lock_yuan, key.timer_period);key.nd = of_find_node_by_path("/key");//在设备树中获取节点key.irq_struct.key_gpio = of_get_named_gpio(key.nd,"key-gpio", 0);//得到gpio引脚ret = gpio_request(key.irq_struct.key_gpio,KEY_NAME);if(ret<0){printk("gpio requst error !\r\n");}ret = gpio_direction_input(key.irq_struct.key_gpio);//设置输入if(ret == 0){ printk("从设备树读取节点和gpio正确\r\n");}else {gpio_free(key.irq_struct.key_gpio);}/*中断设置*/key.irq_struct.irq = gpio_to_irq(key.irq_struct.key_gpio);//获取中断号key.irq_struct.handler = key_irq_hander;//中断函数表注册key.irq_struct.value = KEY_EN_VALUE;//按键值//key.irq_struct.tasklet = tasklet_func;//添加下半部函数taskletmemset(key.irq_struct.gpio_name,0,sizeof(key.irq_struct.gpio_name));strncpy(key.irq_struct.gpio_name, "key0", sizeof(key.irq_struct.gpio_name));//按键名// tasklet_init(&key.irq_struct.tasklet,tasklet_func, (unsigned long)&key);INIT_WORK(&key.irq_struct.testwork,testwork_func_t);ret = request_irq(key.irq_struct.irq,key.irq_struct.handler,IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING,key.irq_struct.gpio_name, &key);if(ret<0){printk("irq requset error !\r\n");}
}static int __init pgkey_init(void)
{gpio_init();//gpio初始化/*注册*//*1.设备号*/if(key.major){key.key_hao = MKDEV(key.major,0);register_chrdev_region(key.key_hao, 1, KEY_NAME);//主动注册}else{alloc_chrdev_region(&key.key_hao, 0, 1, KEY_NAME);//自动注册}printk("major = %d,minor = %d",MAJOR(key.key_hao),MINOR(key.key_hao));/*2.注册函数*/key.cdev.owner = THIS_MODULE;cdev_init(&key.cdev,&pgkey_fops);cdev_add(&key.cdev,key.key_hao,1);/*3.节点申请*/ key.class = class_create(THIS_MODULE,KEY_NAME);key.device = device_create(key.class, NULL,key.key_hao, NULL,KEY_NAME);/*初始化定时器*/init_timer(&key.timer);//初始化定时器key.timer.function = key_timer_function;//定时器函数return 0;
}static void  __exit pgkey_exit(void)
{free_irq(key.irq_struct.irq, &key);del_timer(&key.timer);gpio_free(key.irq_struct.key_gpio);cdev_del(&key.cdev);//先删除设备unregister_chrdev_region(key.key_hao,1);//删除设备号device_destroy(key.class,key.key_hao);//先删除和设备第关系class_destroy(key.class);//再删除类}/*驱动入口和出口*/
module_init(pgkey_init);
module_exit(pgkey_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("wyt");

二,阻塞和非阻塞IO和异步通知

在这里插入图片描述

1.阻塞IO

  这种思想就是让应用程序等一下,等好了,在运行。应用程序在对驱动程序操作时,如果不能获取到资源,阻塞IO会将应用程序休眠,线程挂起,直到能获取到资源时,再进行应用程序的操作。不然应用程序一直对按键进行查询,占用CPU率高达90%以上。

1.1 常见结构1

  利用函数 wait_event_interruptible,放在读函数中,只有在定时器函数中,判断出按键按下,才会唤醒,wake_up_interruptible唤醒等待队列中的线程,驱动函数 wait_event_interruptible下面的内容才能执行,从而应用读取到数据。

wait_queue_head_t r_wait;//等待队列头 
static ssize_t key_read(struct file *filp,  char __user *buf, size_t count, loff_t *ppos)
{static int key_value = 0,ret = 0;struct key_dev *key_read =(struct key_dev *)filp->private_data;wait_event_interruptible(key_read->r_wait,key_pan);//等待事件,当按键按下有效.........return 0;
}
static void key_timer_function(unsigned long arg)//定时结束后会执行第操作,
{......../*唤醒进程*/if(key_pan){wake_up_interruptible(&key_t->r_wait);}
}
init_waitqueue_head(&key.r_wait);//初始化

1.2 常见结构2

  等待队列头是一个链表头,用于管理所有等待某个事件的线程,因为可能有好多文件都调用这个驱动模块。
  等待队列项表示一个正在等待某个事件的线程,表示某一个。

wait_queue_head_t r_wait;//等待队列头 
static ssize_t key_read(struct file *filp,  char __user *buf, size_t count, loff_t *ppos)
{static int key_value = 0,ret = 0;struct key_dev *key_read =(struct key_dev *)filp->private_data;DECLARE_WAITQUEUE(wait,current);//定义的等待队列add_wait_queue(&key_read->r_wait,&wait);//将队列添加到等待队列头__set_current_state(TASK_INTERRUPTIBLE);//设置为可被打断状态,即用kill -9能杀掉schedule();//让出 CPU,线程进入睡眠状态,等待被唤醒/*判断被其他信号唤醒*/if(signal_pending(current)){goto data_error;}......data_error:__set_current_state(TASK_RUNNING);//将当前任务设置为运行状态remove_wait_queue(&key_read->r_wait,&wait);//将对应的队列项从等待队列头删除return 0;
}
static void key_timer_function(unsigned long arg)//定时结束后会执行第操作,
{......../*唤醒进程*/if(key_pan){wake_up_interruptible(&key_t->r_wait);}
}
init_waitqueue_head(&key.r_wait);//初始化

2.非阻塞IO

  这种思想是让应用程序每隔一定时间(很短)查一下,其他时间去干别的事情,当查询好了的话,就可以运行了。应用程序在对驱动程序操作时,如果不能获取到资源,非阻塞IO会一直轮询等待,设置间隔时间,比如200ms,每隔200ms就会去查询驱动能否获取数据。中间的时间,也就是这个200ms内进行其他操作。这个要在应用程序中,打开文档操作加上O_NONBLOCK: fd = open(filename,O_RDWR | O_NONBLOCK);//按照非阻塞方式打开

2.1 驱动结构

wait_queue_head_t r_wait;//等待队列头 
static ssize_t key_read(struct file *filp,  char __user *buf, size_t count, loff_t *ppos)
{static int key_value = 0,ret = 0;struct key_dev *key_read =(struct key_dev *)filp->private_data;if(filp->f_flags & O_NONBLOCK)//判断是阻塞还是非阻塞方式{if(key_pan==0){return -EAGAIN;//非阻塞            }}else wait_event_interruptible(key_read->r_wait,key_pan);//否则按照阻塞方式......
}
static unsigned int key_poll(struct file *filp, struct poll_table_struct *wait)
{int ret = 0;struct key_dev *key_poll = (struct key_dev *)filp->private_data;poll_wait(filp, &key_poll->r_wait, wait);//文件,等待队列头,等待队列项if(key_pan)//poll判断的内容,按键按下可读{ret = POLLIN | POLLRDNORM;}return ret;
}
static struct file_operations pgkey_fops={.owner=THIS_MODULE,.open=pgkey_open,.read=key_read,.release=pgkey_release,.poll = key_poll,};
init_waitqueue_head(&key.r_wait);//初始化

2.2 select 应用程序

  应用程序有两种,poll和select,后者能监视的文件数量有最大限制1024,poll函数没有最大文件限制。

#include "stdio.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "stdlib.h"
#include "string.h"
#include "poll.h"
#include "sys/select.h"
#include "sys/time.h"#include "linux/ioctl.h"
int main(unsigned char argc,unsigned char *argv[])
{int rel = 0,fd = 0,arg = 0;int cmd = 0;struct pollfd fds;fd_set readfds;struct timeval timeout;    unsigned char *filename,value[1]={0};filename = argv[1];fd = open(filename,O_RDWR | O_NONBLOCK);//按照非阻塞方式打开if(fd<0) printf("open file error\r\n");/*select*/while(1){FD_ZERO(&readfds);//清除FD_SET(fd,&readfds);//添加fd到readfds中timeout.tv_sec=0;timeout.tv_usec = 500000;//500msrel = select(fd+1,&readfds,NULL,NULL,&timeout);switch (rel){case 0:printf("time out !!\r\n");break;case -1:break;default:rel = read(fd,value,sizeof(value));if(rel<0){}else{if(value[0]){printf("value = %x\r\n",value[0]);}          }break;}}   rel = close(fd);if(rel<0) printf("close in  APP error\r\n");return 0;
}

2.3 poll 应用程序

```c
#include "stdio.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "stdlib.h"
#include "string.h"
#include "poll.h"
#include "sys/select.h"
#include "sys/time.h"#include "linux/ioctl.h"
int main(unsigned char argc,unsigned char *argv[])
{int rel = 0,fd = 0,arg = 0;int cmd = 0;struct pollfd fds;fd_set readfds;struct timeval timeout;    unsigned char *filename,value[1]={0};filename = argv[1];fd = open(filename,O_RDWR | O_NONBLOCK);//按照非阻塞方式打开if(fd<0) printf("open file error\r\n");fds.fd=fd;fds.events = POLLIN;while(1){rel = poll(&fds,1,1000);switch (rel){case 0:printf("time out !!\r\n");break;case -1:break;default:rel = read(fd,value,sizeof(value));if(rel<0){}else{if(value[0]){printf("value = %x\r\n",value[0]);}          }break;}}rel = close(fd);if(rel<0) printf("close in  APP error\r\n");return 0;
}

3.异步通知

  类似于中断的思想,当驱动中判断出按键按下,发送一个信号,到应用对应的进程中,从而引起应用程序执行读取按键的操作,在应用程序中,类似于中断的方式。
驱动框架:

 struct fasync_struct *key_fasync;//异步通知
static void key_timer_function(unsigned long arg)//定时结束后会执行第操作,
{.......if(key_pan)//按下{printk("in linux  key push  in fasync!\r\n");kill_fasync(&key_t->key_fasync,SIGIO,POLL_IN);//添加异步通知,发送这个信号}
}static int key_file_fasync(int fd,struct file *filp,int on)
{struct key_dev *dev = (struct key_dev *)filp->private_data;return fasync_helper(fd, filp,on,&dev->key_fasync);
}
static int pgkey_release(struct inode *innode,struct file *filp)
{//这段还是之前的释放函数,不过添加异步通知后,在释放文件时,关闭异步通知。return key_file_fasync(-1,filp,0);
}
static struct file_operations pgkey_fops={.owner=THIS_MODULE,.open=pgkey_open,.read=key_read, .fasync =key_file_fasync,.release=pgkey_release,
}; 

  应用程序:这个key_signal就类似于中断函数, signal(SIGIO,key_signal)相当于中断函数注册的意思,从而在应用程序中,将应用程序对应的进程号给内核,并且打开异步通知,内核中驱动程序判断按键按下后,将信号传递给这个应用程序进程,执行key_signal函数,读取按键值。

#include "stdio.h"
#include "unistd.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
#include "stdlib.h"
#include "string.h"
#include "poll.h"
#include "sys/select.h"
#include "sys/time.h"
#include "linux/ioctl.h"
#include "signal.h"
static int fd = 0;
static void key_signal(int num)
{printf("getin APP key_signal\r\n");static int ret =0;unsigned char value = 0;ret = read(fd,&value,sizeof(value));if(ret<0){printf("read error!\r\n");}else {printf("KEY = %d\r\n",value);}
}
int main(unsigned char argc,unsigned char *argv[])
{int rel = 0,arg = 0,flags = 0;struct pollfd fds;fd_set readfds;struct timeval timeout;    unsigned char *filename,value[1]={0};filename = argv[1];fd = open(filename,O_RDWR);//按照阻塞方式打开if(fd<0) printf("open file error\r\n");/*设置信号处理函数*/signal(SIGIO,key_signal);fcntl(fd,F_SETOWN,getpid());//将本应用的进程号告诉内核,从而内核传递的信号到这个进程flags = fcntl(fd,F_GETFD);//获取当前进程状态fcntl(fd,F_SETFL,flags | FASYNC);//开启当前进程异步通知printf("open fasync!\r\n");while(1){sleep(2);}printf("OVER\r\n");rel = close(fd);if(rel<0) printf("close in  APP error\r\n");return 0;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/898597.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Docker和Dify学习笔记

文章目录 1 docker学习1.1 基本命令使用1.1.1 docker ps查看当前正在运行的镜像1.1.2 docker stop停止容器1.1.3 docker compose容器编排1.1.4 docker网络[1] 进入到容器里面敲命令[2] docker network ls[3] brige网络模式下容器访问宿主机的方式 2 Dify的安装和基础使用2.1 下…

探秘Transformer系列之(16)--- 资源占用

探秘Transformer系列之&#xff08;16&#xff09;— 资源占用 文章目录 探秘Transformer系列之&#xff08;16&#xff09;--- 资源占用0x00 概述0x01 背景知识1.1 数据类型1.2 进制&换算数字进制存储度量换算 1.3 参数显存占用有参数的层无参数的层所需资源 1.4 计算量 0…

jaeger安装和简单使用

文章目录 jaeger安装和使用什么是jaegerjaeger安装 jaeger安装和使用 什么是jaeger 官网&#xff1a;https://www.jaegertracing.io/ Jaeger 是一个分布式追踪系统。Jaeger的灵感来自 Dapper 和 OpenZipkin&#xff0c;是一个由 Uber 创建并捐赠给 云原生计算基金会&#xf…

【Mybatis-plus】在mybatis-plus中 if test标签如何判断 list不为空

博主介绍&#xff1a;✌全网粉丝22W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…

【递归,搜索与回溯算法篇】- 名词解释

一. 递归 1. 什么是递归&#xff1f; 定义&#xff1a; 函数自己调用自己的情况关键点&#xff1a; ➀终止条件&#xff1a; 必须明确递归出口&#xff0c;避免无限递归 ➁子问题拆分&#xff1a; 问题需能分解成结构相同的更小的子问题缺点&#xff1a; ➀栈溢出风险&#x…

大屏技术汇集【目录】

Cesium 自从首次发布以来&#xff0c;经历了多个版本的迭代和更新&#xff0c;每个版本都带来了性能改进、新功能添加以及对现有功能的优化。以下是 Cesium 一些重要版本及其主要特点&#xff1a; 主要版本概述 Cesium 1.0 (2012年) 初始版本发布&#xff0c;确立了Cesium作为…

图解AUTOSAR_CP_EEPROM_Abstraction

AUTOSAR EEPROM抽象模块详细说明 基于AUTOSAR标准的EEPROM抽象层技术解析 目录 1. 概述 1.1 核心功能1.2 模块地位2. 架构概览 2.1 架构层次2.2 模块交互3. 配置结构 3.1 主要配置容器3.2 关键配置参数4. 状态管理 4.1 基本状态4.2 状态转换5. 接口设计 5.1 主要接口分类5.2 接…

C++相关基础概念之入门讲解(下)

1. 引用 ​ int main() {const int a10;int& aaa;aa;cout<<aa<<endl; } 引用 不是新定义一个变量&#xff0c;而 是给已存在变量取了一个别名 &#xff0c;编译器不会为引用变量开辟内存空 间&#xff0c;它和它引用的变量 共用同一块内存空间&#xff08;初…

注意力机制,本质上是在做什么?

本文以自注意机制为例&#xff0c;输入一个4*4的矩阵 如下&#xff1a; input_datatorch.tensor([[1,2,3,4], [5,6,7,8], [9,10,11,12], [13,14,15,16] ],dtypetorch.float) 得到Q和K的转置如下。 此时&#xff0c;计算QK^T ,得到如下结果 第一行第一个位置就是第一条样本和第…

Windows搭建免翻墙的BatteryHistorian

文章参考 GitCode - 全球开发者的开源社区,开源代码托管平台 免翻墙的BatteryHistorian主要原理&#xff1a;修改go源码 1.安装Java环境 1.点击下载 Java JDK&#xff0c;并安装,一路next 2.java -version 检验是否安装成功 2.安装Git工具 1、点击下载 Git&#xff0c;并…

WRF/Chem 模式技术解读:为大气污染治理提供有力支撑

技术点目录 第一部分、WRF-Chem模式应用案例和理论基础第二部分、Linux环境配置及WRF-CHEM第三部分、WRF-Chem模式编译&#xff0c;排放源制作第四部分、WRF-Chem数据准备&#xff08;气象、排放、初边界条件等&#xff09;&#xff0c;案例实践第五部分、模拟结果提取、数据可…

ccfcsp2701如此编码

//如此编码 #include<iostream> using namespace std; int main(){int n,m;cin>>n>>m;int a[21],b[21],c[21];for(int i1;i<n;i){cin>>a[i];}c[0]1;for(int i1;i<n;i){c[i]c[i-1]*a[i];}b[1](m%c[1])/c[0];int s1,s20;for(int i2;i<n;i){s2s2…

74HC04(反相器)和74HC14(反相器、施密特触发器)的区别

74HC04和74HC14的具体区别详解 同样具有反相器功能&#xff0c;你知道74HC04和74HC14的具体区别吗&#xff1f; 74HC04 对于74HC04很好理解&#xff0c;输入低电平&#xff0c;输出高电平&#xff1b;输入高电平&#xff0c;输出低电平。 建议操作条件&#xff1a; 下图是TI的…

第十四次CCF-CSP认证(含C++源码)

第十四次CCF-CSP认证 卖菜满分思路 买菜满分思路 再卖菜满分题解&#xff08;差分约束&#xff09;solution 1(枚举 correct but 超时)solution 2(正解) 卖菜 题目链接 满分思路 就是模拟一下这个调整第二天菜价的过程&#xff0c;其中对于两种只有一个邻居的情况下做出调整&…

CCBCISCN复盘

AWDP – ccfrum 自己搭了一下环境, 复现一下这道题目, 之前比赛的时候完全没想到这个漏洞要怎么打, 修也不知道要怎么修, 就仅仅是对用户名的账号和密码进行了一下过滤, 完全没起到作用, 唉, 实在太菜 如果想要尝试复现的话可以尝试拉取这个镜像, 我打完之后就直接把这个容器给…

VS010生成可由MATLAB2016调用的DLL文件方法

亲测实用&#xff0c;不用配置杂七杂八的依赖项 1&#xff1a;新建Win32的DLL输出项目 2&#xff1a;修改为release模式 3&#xff1a;添加calc.cpp文件&#xff0c;即要导出的函数myadd&#xff1a; #include "calc.h" __declspec(dllexport) int myadd(int a,in…

优选算法系列(3.二分查找 )

目录 一.二分查找&#xff08;easy&#xff09; 题目链接&#xff1a;704. 二分查找 - 力扣&#xff08;LeetCode&#xff09; 解法&#xff1a; 代码&#xff1a; 二.在排序数组中查找元素的第⼀个和最后⼀个位置&#xff08;medium&#xff09; 题目链接&#xff1a;34.…

阿里云服务器部署 五 Nginx + springboot

Nginx的部分配置 1. 基础容灾配置&#xff08;被动健康检查&#xff09; 在 upstream 块中&#xff0c;通过 max_fails 和 fail_timeout 参数定义故障转移规则&#xff1a; 在 upstream 块中&#xff0c;通过 max_fails 和 fail_timeout 参数定义故障转移规则&#xff1a;…

接口自动化测试框架详解

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 接口自动化测试是指通过编写程序来模拟用户的行为&#xff0c;对接口进行自动化测试。Python是一种流行的编程语言&#xff0c;它在接口自动化测试中得到了广泛…

C# 项目06-计算程序运行时间

实现需求 记录程序运行时间&#xff0c;当程序退出后&#xff0c;保存程序运行时间&#xff0c;等下次程序再次启动时&#xff0c;继续记录运行时间 运行环境 Visual Studio 2022 知识点 TimeSpan 表示时间间隔。两个日期之间的差异的 TimeSpan 对象 TimeSpan P_TimeSpa…