字符串是创建dm设备的关键,若非在命令行中以参数形式给出,则必然需要写在一个table文件中传给dmsetup。
table字符串有如下形式:
为了弄清楚这些参数,首先必须明白,create、load、reload子命令总是将一个或一组已经存在的块设备A的一部分或者全部虚拟称为块设备B。在内核代码中,块设备B(也是我们直接打交道的设备)称为mapped device,那一组块设备A中指定的那部分抽象(可以看作是我们将它交给dm来管理的那一部分)称为target device(s),对应的驱动为target driver。我们并不要求设备A必须是一个真实的磁盘,它也可以是dm已经虚拟出来的另外一个mapped device。[2] 详尽的解释了mapped device、target driver和target device之间的关系。但是这篇文章并没有着重分析源代码,而这是本文分析的重点。
table字符串中的和是设备A中,交由dm管理的区域,单位是sector。也就是说,由此创建的mapped device刚好映射在源设备中偏移为start、长度为length的这些sectors中;为target driver的类型,每一个type字符串都对应一个target driver;是用来创建target device的参数,这些参数传递给target device的创建函数的形式就如同命令行参数传递给int main(int argc, char *argv[])一样。
Linux内核自带的target driver有linear、stripe、mirror、multi-path、dm-crypt以及一组标准raid的驱动。接下来,我们以stripe的代码为例,来解释target driver是如何创建、运行target device的。
三、Target Driver
每一个target device在内核代码中体现为对应的驱动,这些驱动都必须符合DM构架,受DM的管理。有人可能会疑问,为什么DM构架中的驱动都是target驱动,而不是MD的驱动?因为DM的设计中,MD只是一个对外的统一接口,不同target driver的对外接口都是一样的,因此无需为不同的虚拟方式编写不同的MD,只用提供不同的target driver即可(PS:也许这里叫做mapped driver可以避免混淆,因为MD和target driver(以后简称driver )的实例之间是一对一的关系,而target driver同target device(以后简称target )之间是一对多的关系。将driver的概念融合进入md就变成md与target之间一对多的二元关系,而不是现在的md-driver-target三元关系。但md与driver毕竟一个是通用的,一个是特殊的,由此分解为三元关系也就不难理解)。
再此统一一下术语的简称:我们将mapped device简称为md,target device简称为target。之所以这样简称是因为内核代码的命名规则也大致如此。另外的target driver简称为driver(源代码不会出现,因为DM框架管理的是target,不是driver。driver直接insmod就可以了);源设备简称为device(源代码中只有通过名字包含bdev的变量来代表这些设备)。
本文以dm-stripe.c为例,来分析一个target应该具备哪些基本的要素来完成设计好的设备抽象。stripe所要做的是将多个设备的等长区域合并起来组成一个完成的抽象设备,其重点在于寻址。假设有n个devices,每个的区域长度为m,那么第i个块应该存放在第 (i%n) 个target中的偏移量为 (i/n) 的块(要注意的是实际的偏移还得加上target相对于设备的偏移)。
首先,每个driver需要有一个struct target_type结构向DM注册自己,并且这个结构在所有driver实例间共享,换句话说所有driver实例都可以看作从属于这种类型,因此这个target_type应该理解为driver type才对。dm-stripe的struct target_type结构如下
static struct target_type stripe_target = { .name = "striped", // 名称 .version = {1, 3, 0}, .module = THIS_MODULE, .ctr = stripe_ctr, // 创建器 .dtr = stripe_dtr, // 销毁器 .map = stripe_map, // 映射 .end_io = stripe_end_io,// IO结束通知 .status = stripe_status, .iterate_devices = stripe_iterate_devices, // 迭代遍历源设备 .io_hints = stripe_io_hints, };
创建器、销毁器和映射是一般target driver都具备的功能。
每个创建器都有如下函数原型:
int xxx_ctr(struct dm_target *ti, unsigned int argc, char **argv);
在设备创建时,DM框架会自动创建对应的struct dm_target结构,并力所能及地初始化了一些成员。现在创建器所要做的就是完成对该结构的初始化。那么先来看看DM框架初始化了哪些,需要ctr初始化另外那一些:
struct dm_target { struct dm_table *table; // @driver 到 target device 的映射表,由DM框架维护 struct target_type *type; // @driver 所注册的那个type /* target limits */ sector_t begin; // @ sector_t len; // @ /* Always a power of 2 */ sector_t split_io; // 块大小(每个块的扇区数) /* * A number of zero-length barrier requests that will be submitted * to the target for the purpose of flushing cache. * * The request number will be placed in union map_info->flush_request. * It is a responsibility of the target driver to remap these requests * to the real underlying devices. */ unsigned num_flush_requests; /* target specific data */ void *private; // 自定义的设备相关数据 /* Used to provide an error string from the ctr */ char *error; };
带@标记的成员由DM初始化,或者部分初始化,其他初始化工作由ctr完成。一般来说ctr主要做两件事:
1. 将源设备的dev信息记录到table中。
2. 将target device(s)的信息初始化并记录在private中
table成员就是driver实例到target(s)之间的映射表。DM框架提供了int dm_get_device(struct dm_target *ti, const char *path, sector_t start, sector_t len, fmode_t mode, struct dm_dev **result)函数将path所指定的设备的bdev以及对应的区间、权限、模式等填入ti->table中。stripe_ctr要做的就是将参数中对应的字符串传递给这个函数。
同时,stripe_ctr创建了自定义的struct stripe_c结构sc,并记录在ti->private上。l利用dm_get_device的result出参填满sc->stripes数组(关键就是记住源设备的dev结构,DM中统一用struct dm_dev *指针来引用)。
对应的销毁器stripe_dtr就是将stripe_ctr向内核申请的资源一一释放掉,在此不累述。
最关键的是map函数。任何一个bio(块设备的io请求)都要映射到最终存储它的设备上的相应位置,map函数就是完成这一功能。该函数的原型如下:
int xxx_map(struct dm_target *ti, struct bio *bio, union map_info *map_context);
ti代表target,bio是发给这个target的io请求。一个bio有三个关键成员:bi_sector(位置)、bi_bdev(设备)、bi_io_vec(数据)。DM框架将bio发给map函数,使得target有机会来改变bio的这三个关键成员,从而实现两个目的:重定位和修改数据。map_context在许多情况下并没有许多作用。
如果map函数将bio赋值后又分发出去,那么就返回DM_MAPIO_SUBMITTED告诉DM不要再处理了;如果map函数修改了bio的内容,希望DM将bio按照新内容再分发,那么就返回DM_MAPIO_REMAPPED即可;如果map函数将bio加入队列中等待后续处理,则返回DM_MAPIO_REQUEUE。DM相应的处理代码可以在dm.c中的__map_bio()函数中找到。
stripe_map就很简单了,直接修改bio的bi_sector和bi_bdev,返回DM_MAPIO_REMAPPED通知DM再分发一次即可。stripe所扮演的角色就好比是一个邮件中转站,下辖N个子邮箱。所有邮件都按照规则被转发到对应子邮箱中,中转站的工作就是把每个邮件的地址和收件人改一改再让邮递员送一遍即可,接下来的bio传递路径分析将详细展示这一中转过程。
四、DM转发bio的过程
DM为每一个driver的实例创建一个md作为对外的接口,每一个md在内核中注册成为一个块设备,因此每一个driver的实例就是一个虚拟的块设备。
每一个md通过driver的实例管理一个或多个target,driver的主要工作就是把每个提交给md的bio请求进行数据转换并转发给对应的target。md实现了一个标准的块设备驱动,这里仅分析bio的转发过程。
每个块设备都有一个请求队列,请求队列包含一个make_request_fn指针指向原型为int make_request(struct request_queue *q, struct bio *bio);的函数,Linux内核中的void generic_make_request(struct bio *bio);函数就是通过bio找到对应的bi_bdev,然后找到该bdev对应的request_queue,并调用其make_request_fn函数:
block/blk_core.c 1484行:ret = q->make_request_fn(q, bio);
这就是bio从内核进入DM的起点。为什么这么说?因为在md创建的时候(通过dm.c中alloc_dev())将md->queue的make_request_fn指针设置为了dm_request:
drivers/md/dm.c 1908行:blk_queue_make_request(md->queue, dm_request);
dm_request接收到bio之后有两种选择:如果q->queue_flags被设置了QUEUE_FLAG_STACKABLE,则对request进行排队处理,否则直接分发。alloc_dev中创建queue的时候按照QUEUE_FLAG_DEFAULT创建,包含了QUEUE_FLAG_STACKABLE,但是接着该标志被清除了:
drivers/md/dm.c 1889行:md->queue = blk_init_queue(dm_request_fn, NULL);
...
drivers/md/dm.c 1903行:queue_flag_clear_unlocked(QUEUE_FLAG_STACKABLE, md->queue);
因此dm_request()函数将走_dm_request()分支。以下是bio所走过的流程:
int dm_request(struct request_queue *q, struct bio *bio)
`-> _dm_request(q, bio);
`-> __split_and_process_bio(md, bio); // md 由 q->queue_data 获得
`-> __clone_and_map(&ci); // md、bio等信息记录在 ci 结构体中
`-> __map_bio(ti, clone, tio); // ti 由 ci->md 查表获得,clone由ci->bio克隆获得
`-> ti->type->map(ti, clone, &tio->info);
最终,bio传递给了对应ti的map函数。
要说明的是,DM构架及其驱动一般不会是真实设备的驱动,因此只会对bio进行处理之后再转发出去。转发的方法就是修改bio->bi_bdev和bio->bi_sector。其中bi_bdev必需是在内核中已注册的设备,这些块设备和dm的块设备一道在Linux内核中注册,在Linux看来是平等的。而一个md其实是将其他块设备的bdev记录在自己的映射表中,按照自身的逻辑规律对bio进行映射转发而已。
参考文献
[1] dmsetup(8) - Linux man page
[2] Linux 内核中的 Device Mapper 机制
你可能感兴趣的:(Linux,其他)
【深入理解Linux锁机制】五、衍生自旋锁
dong__ge
深入理解Linux驱动程序开发 # Linux内核锁 Linux锁机制 Linux锁 内核锁 Linux驱动开发 Linux
系列文章:我的圈子:高级工程师聚集地【深入理解Linux锁机制】一、内核锁的由来【深入理解Linux锁机制】二、中断屏蔽【深入理解Linux锁机制】三、原子操作【深入理解Linux锁机制】四、自旋锁【深入理解Linux锁机制】五、衍生自旋锁【深入理解Linux锁机制】六、信号量【深入理解Linux锁机制】七、互斥体【深入理解Linux锁机制】八、完成量
『 Linux 』线程安全的单例模式,自旋锁与读写锁
Dio夹心小面包
线程 Linux C++ linux 单例模式 javascript 服务器 c++ 运维
文章目录单例模式懒汉模式与饿汉模式自旋锁读写锁单例模式单例模式是一种创建型设计模式,其主要目的是确保一个类只有一个实例,并提供一个全局访问点来访问该实例;这在需要严格控制如何及合适访问某个唯一资源型下有一定作用;单利模式的主要特点为如下:私有构造函数单例模式通常要将构造私有化,以保证无法直接通过该类实例化出对应的对象;只能通过该类提供对应的接口来实例化整个对象,确保只有一个实例;私有静态实例私有静
Fiber是什么?
醉方休
react.js
对React的Fiber架构的理解需要从React的核心目标与面临的挑战说起。它本质上是React16引入的全新协调(Reconciliation)引擎,旨在解决React15及之前版本在处理大型应用和复杂更新时遇到的根本性性能瓶颈和用户体验问题。核心理解:Fiber是什么?虚拟的底层数据结构:Fiber是对React组件、DOM节点或其他UI元素的轻量级、链式表示的JavaScript对象。每个
spring-initializer
魔芋红茶
spring spring 学习 python
spring-initializer能做什么从Spring官网下载并解压以生成springboot框架代码。存在的意义一般通过Idea从https://start.spring.io/下载框架代码,但很诡异的是,经常会出现浏览器可以访问,但Idea无法下载的问题,尝试通过curl等Linux命令行web客户端下载,依然有概率出现连接超时的问题。网上给出的解决方案是将Spring官网源替换为阿里源,
DM 数据库操作全指南
2301_82150492
数据库
一、DM数据库安装系统要求检查确保操作系统满足DM数据库的要求,例如,对于Linux系统,检查内核版本、内存、磁盘空间等。以CentOS7为例,推荐内存至少1GB,磁盘空间剩余5GB以上。检查是否安装了必要的依赖库,如glibc等。下载DM数据库安装包从达梦官方网站(武汉达梦数据库股份有限公司)下载适合操作系统的DM数据库安装包,如DM8的Linux版安装包。安装步骤以root用户登录系统,进入安
DM 数据库概述
2301_82150492
数据库
目录DM数据库概述安装DM数据库实例配置详解备份与还原策略DM数据库函数运用SQL查询语句实战DMSQL程序设计总结与展望引言达梦数据库(DM)是一款国产的高性能数据库管理系统,具有丰富的功能和良好的兼容性,广泛应用于各类企业级应用场景。它支持多种操作系统,如Windows、Linux等,并提供了完善的数据库管理工具和开发接口。安装DM数据库系统准备在安装DM数据库之前,需要确保目标系统满足一定的
HTTP 缓存
介绍HTTP缓存是Web性能优化中至关重要的一个概念。当客户端(如浏览器)向服务器发出请求时,服务器会返回一个响应,这个响应可以被缓存并存储。下次当客户端发出相同请求时,缓存可以直接提供先前存储的响应,而不必再向源服务器发起请求。HTTP缓存减少了重复的网络请求和服务器负载,提高了整体的响应速度。缓存类型私有缓存(PrivateCache)私有缓存是与特定客户端绑定的缓存,由于存储的响应不与其他客
javascript基础从小白到高手系列四千八百七十一:读取响应状态信息
完美句号
javascript 开发语言 ecmascript
Response对象包含一组只读属性,描述了请求完成后的状态,如下表所示。属性值headers响应包含的Headers对象ok布尔值,表示HTTP状态码的含义。200~299的状态码返回true,其他状态码返回falseredirected布尔值,表示响应是否至少经过一次重定向status整数,表示响应的HTTP状态码statusText字符串,包含对HTTP状态码的正式描述。这个值派生自可选的H
javascript基础从小白到高手系列四千八百七十二:数值范围
除了"email"和"url",HTML5还定义了其他几种新的输入元素类型,它们都是期待某种数值输入的,包括:“number”、“range”、“datetime”、“datetime-local”、“date”、“month”、“week”和"time"。并非所有主流浏览器都支持这些类型,因此使用时要当心。浏览器厂商目前正致力于解决兼容性问题和提供更逻辑化的功能。本节内容更多地是介绍未来趋势,而
docker-compose报错ERROR: Invalid interpolation format for “web“ option in service “services“:
reiraoy
docker java 容器
1.问题在Linux中使用docker-compose过一段时间后再次使用docker-compose命令启动或关闭容器报错:ERROR:Invalidinterpolationformatfor"web"optioninservice"services":2.解决思路DockerCompose1.24.1版本对于复杂的变量插值(特别是带有默认值-和:混合使用)的解析非常严格甚至存在一些已知的问题
【Note】《深入理解Linux内核》 Chapter 15 :深入理解 Linux 页缓存
CodeWithMe
读书笔记 linux linux 缓存 spring
《深入理解Linux内核》Chapter15:深入理解Linux页缓存关键词:页缓存、address_space、radixtree、page、writeback、dirtypage、mmap、文件系统缓存、文件I/O性能优化、directI/O一、页缓存是什么?为什么重要?1.1定义页缓存(pagecache)是Linux内核用于缓存文件内容的内存区域,避免每次文件读写都访问磁盘。1.2页缓存的
linux/ubuntu日志管理--/dev/log 的本质与作用
奇妙之二进制
# 嵌入式/Linux linux ubuntu 运维
文章目录**一、基本概念****二、技术细节:UNIX域套接字****三、在不同日志系统中的角色****四、应用程序如何使用`dev/log`****五、查看和验证`/dev/log`****六、总结`/dev/log`的核心作用**一、基本概念/dev/log是一个UNIX域套接字(UnixDomainSocket),是Linux系统中实现进程间通信(IPC)的一种特殊文件。它为应用程序提供了向
剖析AI人工智能领域Whisper的性能指标
AI大模型应用实战
人工智能 whisper xcode ai
剖析AI人工智能领域Whisper的性能指标关键词:Whisper、语音识别、性能指标、ASR、AI模型评估、基准测试、语音转文本摘要:本文深入剖析OpenAI开发的Whisper语音识别系统的性能指标。我们将从技术原理、架构设计、性能基准测试等多个维度,全面分析Whisper在不同场景下的表现。文章将详细讲解Whisper的评估方法、关键性能指标解读、实际应用中的性能表现,以及与其他主流语音识别
ubuntu 18.04系统的镜像源
weixin_45081353
ubunt 日常操作 ubuntu linux 运维
1国内可用的镜像源Ubuntu官方下载地址阿里云开源镜像站清华大学开源镜像站中国科技大学开源镜像站华为云开源镜像站2ubuntu18.04镜像说明Ubuntu18.04是一个广泛使用的Linux发行版,它有多个版本的镜像可供下载。在物理机上安装的镜像如带desktop字样的镜像,含桌面环境,适合办公如带server字样的镜像,无桌面环境,适合部署服务器在虚拟机中安装的镜像仅用于制作启动介质的镜像在
Linux 云服务器开启 SSH 会话保持,避免长时间断开连接 #Linux #SSH #云服务器 #CentOS #会话保持 #运维
代码简单说
运维宝典限时特惠 linux 服务器 运维 SSH 会话保持
Linux云服务器开启SSH会话保持,避免长时间断开连接标签:#Linux#SSH#云服务器#CentOS#会话保持#运维操作场景在使用SSH登录CentOS云服务器时,很多开发者都会遇到一个常见问题:长时间不操作后,SSH会话自动断开,导致需要重新登录。这种情况不仅影响开发效率,还可能中断正在执行的任务。本文将详细介绍如何通过配置SSH服务端,保持SSH会话持续连接,避免自动断开。注意:本文涉及
在Ubuntu系统中更改镜像源【笔记】
AnsonNie
Ubuntu 笔记 服务器 ubuntu 笔记 linux
这里以华为镜像源为例,其他配置类似。以下是具体步骤和示例代码:1.打开终端。2.备份镜像源源文件。sudocp/etc/apt/sources.list/etc/apt/sources.list.bak3.注释掉原有的源地址(在每一行前加上#)。4.在文件中添加华为镜像源地址。以Ubuntu20.04为例,可以添加以下内容:sudovim/etc/apt/sources.listdebhttp:/
从零到精通:Linux上的Conda环境详细教程
第一章:Conda简介Conda的定义Conda是一个开源的包管理系统和环境管理系统,可以在多个平台上安装、运行和更新软件包和依赖项。Conda最初是为Python和R语言的数据科学包创建的,但现在支持多种编程语言和工具。Conda的主要功能和优势包管理:Conda能够自动处理包的依赖关系,确保每个包所需的库和工具都被正确安装。它支持从各种渠道安装包,如CondaForge和Anaconda官方仓
深入理解 grep 命令:从基础匹配到正则表达式的全面指南
线条1
正则表达式 java 数据库
一、grep命令概述在Linux系统中,grep(GlobalRegularExpressionPrint)是一个强大的文本搜索工具,它能够使用正则表达式在文本文件中查找匹配的行,并将这些行输出。从系统管理员到开发人员,grep都是日常工作中不可或缺的工具,广泛应用于日志分析、代码搜索、数据过滤等场景。二、grep基础匹配用法1.普通文本匹配命令格式:grep"pattern"filename示例
【AIDD药物研发】张载熙-生成式AI4药物发现
静静喜欢大白
医疗影像 人工智能 AIDD 药物研究 药物生成 生成
目录1、简介2、生成式AI用于基于结构式的药物发现背景生成用于靶标结合的类药小分子功能性蛋白质的生成与优化其他新的药物形式及生物安全/安全性小结3、参考4、补充学习资料1、简介最近需要简单了解喜爱AIDD流程以及相关进展调研,看到zaixizhang正在做相关研究,进行下面的学习记录张载熙中国科学技术大学计算机科学与技术学院2021级博士生(导师刘淇教授),认知智能全国重点实验成员,本科毕业于中国
第五章 LINUX 用户管理
5.1用户和组概念1主要命令:用户增删查改useradduserdelid或cat/etc/passwdusermod组增删查改groupaddgroupdelcat/etc/groupgroupmems或gpasswdid##查看当前用户的uidgid附属组(G)-u##显示用户的唯一标识符(UID)。-g##显示用户所属组的标识符(GID)。-G##显示用户所属的所有组的标识符。2什么是用户和
逻辑卷的创建和扩容linux
suijishengchengde
linux 运维 服务器
--创建逻辑卷1、lsblk、blkid查看磁盘是否可以正常显示2、制作物理卷,pvcreate/dev/sdb--如果需要磁盘分区,MBR(2T以下)方式,可以使用fdisk命令n#创建新分区p#选择主分区(e扩展分区)#选择分区号(如果需要)#指定起始位置#指定分区大小w#保存更改并退出--也可以使用GPT(2T以上)方式使用gdisk命令,方法同fdisk--还可以用parted命令sudo
引入组件时报错:已被代码依赖分析忽略,无法被其他模块引用
引入组件时报错:已被代码依赖分析忽略,无法被其他模块引用。在uniapp中找到manifest.json文件,通过源码视图编辑,在小程序特有相关出添加下面两行即可"ignoreDevUnusedFiles":false,"ignoreUploadUnusedFiles":false,
C++语言标准
Shy_tom
C++ c++
title:C++语言标准description:C++标准C++语言的起源 与C语言一样,C++也是在贝尔实验室诞生的,BjarneStroustrup于20世纪80年代在这里开发出了这种语言。用他自己的话来说,“C++主要是为了我的朋友和我不必再使用汇编语言、C语言或者其他现代高级语言来编程而设计的。它的主要功能是可以更方便地编写出好程序,让每个程序员更加快乐”。C++语言标准 美国国家标准委
【java】list集合遍历的5种方式
IT_Most
java 集合 java
平凡也就两个字:懒和惰;成功也就两个字:苦和勤;优秀也就两个字:你和我。跟着我从0学习JAVA、spring全家桶和linux运维等知识,带你从懵懂少年走向人生巅峰,迎娶白富美!关注微信公众号【IT特靠谱】,每天都会分享技术心得~【java】list集合遍历的5种方式List集合在Java日常开发中是非常常见的,快速选择合适的遍历方式能极大提高我们的开发效率。下面我总结了五种List集合的遍历方式
Linux(Debian)下部署.NET Core网站终极指南:从零到生产级服务的深度实战!
墨夶
C#学习资料 linux debian .netcore
**Debian部署.NETCore的“全栈实战”**第一阶段:环境准备与依赖安装1.1系统环境要求#更新系统并安装基础工具sudoaptupdate&&sudoaptupgrade-ysudoaptinstall-ycurlnanounzipgit1.2安装.NETCore运行时代码示例(Debian11/12):#下载并安装MicrosoftGPG密钥wgethttps://packages.
【Linux】各版本系统静态IP设置、更换镜像源
这里将会对每个OS的主流版本展示详细的操作过程,将持续更新~以下命令都是基于root用户权限下的操作哦~~如果没有请在命令前添加sudo即可。目录一、CentOSLinux7.91.IP设置2.更换镜像源二、RedHat8.101.IP设置2.更换镜像源三、RockyLinux8.101.IP设置2.更换镜像源四、RockyLinux9.51.IP设置2.更换镜像源一、CentOSLinux7.9
【LangChain编程:从入门到实践】LangChain与其他框架的比较
AI天才研究院
Agentic AI 实战 计算 AI人工智能与大数据 计算科学 神经计算 深度学习 神经网络 大数据 人工智能 大型语言模型 AI AGI LLM Java Python 架构设计 Agent RPA
【LangChain编程:从入门到实践】LangChain与其他框架的比较1.背景介绍1.1人工智能发展现状在当今时代,人工智能(AI)已经成为科技领域中最热门和最具革命性的话题之一。随着计算能力的不断提升和算法的持续优化,AI系统正在不断扩展其应用范围,包括自然语言处理、计算机视觉、决策系统等各个领域。1.2LangChain概述在这种背景下,LangChain作为一个新兴的AI框架应运而生。L
WSL命令
走过,莫回头
Linux wsl
以下是WSL(WindowsSubsystemforLinux)的常用命令大全,涵盖安装、管理、网络、文件交互等场景,方便快速查阅和使用:1.安装与版本管理命令说明wsl--install默认安装WSL和Ubuntuwsl--install-d指定安装其他发行版(如Debian、Kali-linux)wsl--update更新WSL内核wsl--set-default-version2设置新发行版
Python运算符简介
满目828
python 开发语言 初学者 运算符
目录一.算术运算符二.赋值运算符三.比较运算符四.逻辑运算符五.其他运算符六.运算符优先级一.算术运算符算术运算符包含:+,-,*,/,**,//,%(注:在运算过程中如含有小数,则结果为float类型(小数))+(加法运算符)a=10b=20#+result=a+bprint(result)print(3+4)-(减法运算符)a=10b=20#-result=a-bprint(result)pr
Java的神奇绘图功能:画一条直线
一、背景引入第一篇介绍了如何设置一个简单的登录界面,今天就来讲讲界面JFrame的其他功能:绘图,但作为向递归分形的过渡内容,我们今天不需要画出多复杂多精美的图案,只需要在界面上能够画出一条简单的直线即可。二、问题思考1.摆在眼前的问题与资源需要解决的问题:如何实现画一条直线?可以解决问题的资源:有关Java的一些基础知识和简单的界面基础2.怎么画一条直线(1)猜想:画一条直线的可能流程首先是画一
sql统计相同项个数并按名次显示
朱辉辉33
java oracle
现在有如下这样一个表:
A表
ID Name time
------------------------------
0001 aaa 2006-11-18
0002 ccc 2006-11-18
0003 eee 2006-11-18
0004 aaa 2006-11-18
0005 eee 2006-11-18
0004 aaa 2006-11-18
0002 ccc 20
Android+Jquery Mobile学习系列-目录
白糖_
JQuery Mobile
最近在研究学习基于Android的移动应用开发,准备给家里人做一个应用程序用用。向公司手机移动团队咨询了下,觉得使用Android的WebView上手最快,因为WebView等于是一个内置浏览器,可以基于html页面开发,不用去学习Android自带的七七八八的控件。然后加上Jquery mobile的样式渲染和事件等,就能非常方便的做动态应用了。
从现在起,往后一段时间,我打算
如何给线程池命名
daysinsun
线程池
在系统运行后,在线程快照里总是看到线程池的名字为pool-xx,这样导致很不好定位,怎么给线程池一个有意义的名字呢。参照ThreadPoolExecutor类的ThreadFactory,自己实现ThreadFactory接口,重写newThread方法即可。参考代码如下:
public class Named
IE 中"HTML Parsing Error:Unable to modify the parent container element before the
周凡杨
html 解析 error readyState
错误: IE 中"HTML Parsing Error:Unable to modify the parent container element before the child element is closed"
现象: 同事之间几个IE 测试情况下,有的报这个错,有的不报。经查询资料后,可归纳以下原因。
java上传
g21121
java
我们在做web项目中通常会遇到上传文件的情况,用struts等框架的会直接用的自带的标签和组件,今天说的是利用servlet来完成上传。
我们这里利用到commons-fileupload组件,相关jar包可以取apache官网下载:http://commons.apache.org/
下面是servlet的代码:
//定义一个磁盘文件工厂
DiskFileItemFactory fact
SpringMVC配置学习
510888780
spring mvc
spring MVC配置详解
现在主流的Web MVC框架除了Struts这个主力 外,其次就是Spring MVC了,因此这也是作为一名程序员需要掌握的主流框架,框架选择多了,应对多变的需求和业务时,可实行的方案自然就多了。不过要想灵活运用Spring MVC来应对大多数的Web开发,就必须要掌握它的配置及原理。
一、Spring MVC环境搭建:(Spring 2.5.6 + Hi
spring mvc-jfreeChart 柱图(1)
布衣凌宇
jfreechart
第一步:下载jfreeChart包,注意是jfreeChart文件lib目录下的,jcommon-1.0.23.jar和jfreechart-1.0.19.jar两个包即可;
第二步:配置web.xml;
web.xml代码如下
<servlet>
<servlet-name>jfreechart</servlet-nam
我的spring学习笔记13-容器扩展点之PropertyPlaceholderConfigurer
aijuans
Spring3
PropertyPlaceholderConfigurer是个bean工厂后置处理器的实现,也就是BeanFactoryPostProcessor接口的一个实现。关于BeanFactoryPostProcessor和BeanPostProcessor类似。我会在其他地方介绍。PropertyPlaceholderConfigurer可以将上下文(配置文件)中的属性值放在另一个单独的标准java P
java 线程池使用 Runnable&Callable&Future
antlove
java thread Runnable callable future
1. 创建线程池
ExecutorService executorService = Executors.newCachedThreadPool();
2. 执行一次线程,调用Runnable接口实现
Future<?> future = executorService.submit(new DefaultRunnable());
System.out.prin
XML语法元素结构的总结
百合不是茶
xml 树结构
1.XML介绍1969年 gml (主要目的是要在不同的机器进行通信的数据规范)1985年 sgml standard generralized markup language1993年 html(www网)1998年 xml extensible markup language
改变eclipse编码格式
bijian1013
eclipse 编码格式
1.改变整个工作空间的编码格式
改变整个工作空间的编码格式,这样以后新建的文件也是新设置的编码格式。
Eclipse->window->preferences->General->workspace-
javascript中return的设计缺陷
bijian1013
JavaScript AngularJS
代码1:
<script>
var gisService = (function(window)
{
return
{
name:function ()
{
alert(1);
}
};
})(this);
gisService.name();
&l
【持久化框架MyBatis3八】Spring集成MyBatis3
bit1129
Mybatis3
pom.xml配置
Maven的pom中主要包括:
MyBatis
MyBatis-Spring
Spring
MySQL-Connector-Java
Druid
applicationContext.xml配置
<?xml version="1.0" encoding="UTF-8"?>
&
java web项目启动时自动加载自定义properties文件
bitray
java Web 监听器 相对路径
创建一个类
public class ContextInitListener implements ServletContextListener
使得该类成为一个监听器。用于监听整个容器生命周期的,主要是初始化和销毁的。
类创建后要在web.xml配置文件中增加一个简单的监听器配置,即刚才我们定义的类。
<listener>
<des
用nginx区分文件大小做出不同响应
ronin47
昨晚和前21v的同事聊天,说到我离职后一些技术上的更新。其中有个给某大客户(游戏下载类)的特殊需求设计,因为文件大小差距很大——估计是大版本和补丁的区别——又走的是同一个域名,而squid在响应比较大的文件时,尤其是初次下载的时候,性能比较差,所以拆成两组服务器,squid服务于较小的文件,通过pull方式从peer层获取,nginx服务于较大的文件,通过push方式由peer层分发同步。外部发布
java-67-扑克牌的顺子.从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的.2-10为数字本身,A为1,J为11,Q为12,K为13,而大
bylijinnan
java
package com.ljn.base;
import java.util.Arrays;
import java.util.Random;
public class ContinuousPoker {
/**
* Q67 扑克牌的顺子 从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。
* 2-10为数字本身,A为1,J为1
翟鸿燊老师语录
ccii
翟鸿燊
一、国学应用智慧TAT之亮剑精神A
1. 角色就是人格
就像你一回家的时候,你一进屋里面,你已经是儿子,是姑娘啦,给老爸老妈倒怀水吧,你还觉得你是老总呢?还拿派呢?就像今天一样,你们往这儿一坐,你们之间是什么,同学,是朋友。
还有下属最忌讳的就是领导向他询问情况的时候,什么我不知道,我不清楚,该你知道的你凭什么不知道
[光速与宇宙]进行光速飞行的一些问题
comsci
问题
在人类整体进入宇宙时代,即将开展深空宇宙探索之前,我有几个猜想想告诉大家
仅仅是猜想。。。未经官方证实
1:要在宇宙中进行光速飞行,必须首先获得宇宙中的航行通行证,而这个航行通行证并不是我们平常认为的那种带钢印的证书,是什么呢? 下面我来告诉
oracle undo解析
cwqcwqmax9
oracle
oracle undo解析2012-09-24 09:02:01 我来说两句 作者:虫师收藏 我要投稿
Undo是干嘛用的? &nb
java中各种集合的详细介绍
dashuaifu
java 集合
一,java中各种集合的关系图 Collection 接口的接口 对象的集合 ├ List 子接口 &n
卸载windows服务的方法
dcj3sjt126com
windows service
卸载Windows服务的方法
在Windows中,有一类程序称为服务,在操作系统内核加载完成后就开始加载。这里程序往往运行在操作系统的底层,因此资源占用比较大、执行效率比较高,比较有代表性的就是杀毒软件。但是一旦因为特殊原因不能正确卸载这些程序了,其加载在Windows内的服务就不容易删除了。即便是删除注册表中的相 应项目,虽然不启动了,但是系统中仍然存在此项服务,只是没有加载而已。如果安装其他
Warning: The Copy Bundle Resources build phase contains this target's Info.plist
dcj3sjt126com
ios xcode
http://developer.apple.com/iphone/library/qa/qa2009/qa1649.html
Excerpt:
You are getting this warning because you probably added your Info.plist file to your Copy Bundle
2014之C++学习笔记(一)
Etwo
C++ Etwo Etwo iterator 迭代器
已经有很长一段时间没有写博客了,可能大家已经淡忘了Etwo这个人的存在,这一年多以来,本人从事了AS的相关开发工作,但最近一段时间,AS在天朝的没落,相信有很多码农也都清楚,现在的页游基本上达到饱和,手机上的游戏基本被unity3D与cocos占据,AS基本没有容身之处。so。。。最近我并不打算直接转型
js跨越获取数据问题记录
haifengwuch
jsonp json Ajax
js的跨越问题,普通的ajax无法获取服务器返回的值。
第一种解决方案,通过getson,后台配合方式,实现。
Java后台代码:
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String ca
蓝色jQuery导航条
ini
JavaScript html jquery Web html5
效果体验:http://keleyi.com/keleyi/phtml/jqtexiao/39.htmHTML文件代码:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>jQuery鼠标悬停上下滑动导航条 - 柯乐义<
linux部署jdk,tomcat,mysql
kerryg
jdk tomcat linux mysql
1、安装java环境jdk:
一般系统都会默认自带的JDK,但是不太好用,都会卸载了,然后重新安装。
1.1)、卸载:
(rpm -qa :查询已经安装哪些软件包;
rmp -q 软件包:查询指定包是否已
DOMContentLoaded VS onload VS onreadystatechange
mutongwu
jquery js
1. DOMContentLoaded 在页面html、script、style加载完毕即可触发,无需等待所有资源(image/iframe)加载完毕。(IE9+)
2. onload是最早支持的事件,要求所有资源加载完毕触发。
3. onreadystatechange 开始在IE引入,后来其它浏览器也有一定的实现。涉及以下 document , applet, embed, fra
sql批量插入数据
qifeifei
批量插入
hi,
自己在做工程的时候,遇到批量插入数据的数据修复场景。我的思路是在插入前准备一个临时表,临时表的整理就看当时的选择条件了,临时表就是要插入的数据集,最后再批量插入到数据库中。
WITH tempT AS (
SELECT
item_id AS combo_id,
item_id,
now() AS create_date
FROM
a
log4j打印日志文件 如何实现相对路径到 项目工程下
thinkfreer
Web log4j 应用服务器 日志
最近为了实现统计一个网站的访问量,记录用户的登录信息,以方便站长实时了解自己网站的访问情况,选择了Apache 的log4j,但是在选择相对路径那块 卡主了,X度了好多方法(其实大多都是一样的内用,还一个字都不差的),都没有能解决问题,无奈搞了2天终于解决了,与大家分享一下
需求:
用户登录该网站时,把用户的登录名,ip,时间。统计到一个txt文档里,以方便其他系统调用此txt。项目名
linux下mysql-5.6.23.tar.gz安装与配置
笑我痴狂
mysql linux unix
1.卸载系统默认的mysql
[root@localhost ~]# rpm -qa | grep mysql
mysql-libs-5.1.66-2.el6_3.x86_64
mysql-devel-5.1.66-2.el6_3.x86_64
mysql-5.1.66-2.el6_3.x86_64
[root@localhost ~]# rpm -e mysql-libs-5.1