搜档网
当前位置:搜档网 › linux中select函数

linux中select函数

linux中select函数
linux中select函数

select函数:

系统提供select函数来实现多路复用输入/输出模型。原型:

#include

#include

select函数:

系统提供select函数来实现多路复用输入/输出模型。原型:

#include

#include

int select(int maxfd,fd_set *rdset,fd_set *wrset,fd_set *exset,struct timeval *timeout);

参数maxfd是需要监视的最大的文件描述符值+1;rdset,wrset,exset分别对应于需要检测的可读文件描述符的集合,可写文件描述符的集合及异常文件描述符的集合。struct timeval结构用于描述一段时间长度,如果在这个时间内,需要监视的描述符没有事件发生则函数返回,返回值为0。

FD_ZERO,FD_SET,FD_CLR,FD_ISSET: 参数maxfd是需要监视的最大的文件描述符值+1;rdset,wrset,exset分别对应于需要检测的可读文件描述符的集合,可写文件描述符的集合及异常文件描述符的集合。struct timeval结构用于描述一段时间长度,如果在这个时间内,需要监视的描述符没有事件发生则函数返回,返回值为0。

FD_ZERO,FD_SET,FD_CLR,FD_ISSET:

FD_ZERO(fd_set *fdset);将指定的文件描述符集清空,在对文件描述符集合进行设置前,必须对其进行初始化,如果不清空,由于在系统分配内存空间后,通常并不作清空处理,所以结果是不可知的。

FD_SET(fd_set *fdset);用于在文件描述符集合中增加一个新的文件描述符。

FD_CLR(fd_set *fdset);用于在文件描述符集合中删除一个文件描述符。

FD_ISSET(int fd,fd_set *fdset);用于测试指定的文件描述符是否在该集合中。

struct timeval结构:

struct timeval{

long tv_sec;//second

long tv_usec;//minisecond

}

timeout设置情况:

null:select将一直被阻塞,直到某个文件描述符上发生了事件。

0:仅检测描述符集合的状态,然后立即返回,并不等待外部事件的发生。

特定的时间值:如果在指定的时间段里没有事件发生,select将超时返回。

--

('fd_set') 是一组文件描述符(fd)的集合。由于fd_set类型的长度在不同平台上不同,因此应该用一组标准的宏定义来处理此类变量:

fd_set set; FD_ZERO(&set); /* 将set清零*/ FD_SET(fd, &set); /* 将fd加入set */ FD_CLR(fd, &set); /* 将fd从set中清除*/ FD_ISSET(fd, &set); /* 如果fd在set中则真*/ 在过去,一个fd_set通常只能包含少于等于32个文件描述符,因为fd_set其实只用了一个int的比特矢量来实现,在大多数情况下,检查fd_set能包括任意值的文件描述符是系统的责任,但确定你的fd_set到底能放多少有时你应该检查/修改宏FD_SETSIZE的值。*这个值是系统相关的*,同时检查你的系统中的select() 的man手册。有一些系统对多于1024个文件描述符的支持有问题。

多路复用的方式是真正实用的服务器程序,非多路复用的网络程序只能作为学习或着陪

测的角色。本文说下个人

接触过的多路复用函数:select/poll/epoll/port。kqueue的*nix系统没接触过,估计熟悉了上面

四种,kqueue也只是需要熟悉一下而已。

一、select模型

select原型:int select(int n ,fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

其中参数n表示监控的所有fd中最大值+1。

和select模型紧密结合的四个宏,含义不解释了:

FD_CLR(int fd, fd_set *set);

FD_ISSET(int fd, fd_set *set);

FD_SET(int fd, fd_set *set);

FD_ZERO(fd_set *set);

理解select模型的关键在于理解fd_set,为说明方便,取fd_set长度为1字节,fd_set 中的每一bit可以对应一个文件描述符fd。则1字节长的fd_set最大可以对应8个fd。

(1)执行fd_set set; FD_ZERO(&set);则set用位表示是0000,0000。

(2)若fd=5,执行FD_SET(fd,&set);后set变为0001,0000(第5位置为1)

(3)若再加入fd=2,fd=1,则set变为0001,0011

(4)执行select(6,&set,0,0,0)阻塞等待

(5)若fd=1,fd=2上都发生可读事件,则select返回,此时set变为0000,0011。注意:没有事件发生的fd=5被清空。

基于上面的讨论,可以轻松得出select模型的特点:

(1)可监控的文件描述符个数取决与sizeof(fd_set)的值。我这边服务器上sizeof(fd_set)=512,每bit表示一个文件描述符,则我服务器上支持的最大文件描述符是512*8=4096。据说可调,另有说虽然可调,但调整上限受于编译内核时的变量值。本人对调整fd_set的大小不太感兴趣,参考https://www.sodocs.net/doc/bb2011634.html, /CppExplore/archive/2008/03/21/45061.html中的模型2(1)可以有效突破select可监控的文件描述符上限。

(2)将fd加入select监控集的同时,还要再使用一个数据结构array保存放到select 监控集中的fd,一是用于再select 返回后,array作为源数据和fd_set进行FD_ISSET判断。二是select返回后会把以前加入的但并无事件发生的fd清空,则每次开始select前都要重新从array取得fd逐一加入(FD_ZERO最先),扫描array的同时取得fd最大值maxfd,用于select的第一个参数。

(3)可见select模型必须在select前循环array(加fd,取maxfd),select返回后循环array(FD_ISSET判断是否有时间发生)。

下面给一个伪码说明基本select模型的服务器模型:

array[slect_len];

nSock=0;

array[nSock++]=listen_fd;(之前listen port已绑定并listen)

maxfd=listen_fd;

while{

FD_ZERO(&set);

foreach (fd in array)

{

fd大于maxfd,则maxfd=fd

FD_SET(fd,&set)

}

res=select(maxfd+1,&set,0,0,0);

if(FD_ISSET(listen_fd,&set))

{

newfd=accept(listen_fd);

array[nsock++]=newfd;

if(--res<=0) continue

}

foreach 下标1开始(fd in array)

{

if(FD_ISSET(fd,&tyle="COLOR: #ff0000">set))

执行读等相关操作

如果错误或者关闭,则要删除该fd,将array中相应位置和最后一个元素互换就好,nsock减一

if(--res<=0) continue

}

}

服务器端代码:

引用

#include

#include

#include

#include

#include

#include

#include

#include

int main()

{

int server_sockfd, client_sockfd;

int server_len, client_len;

struct sockaddr_in server_address;

struct sockaddr_in client_address;

int result;

fd_set readfds, testfds;

/*创建套接字:IPv4, tcp流套接字*/

server_sockfd = socket(AF_INET, SOCK_STREAM, 0);

server_address.sin_family = AF_INET;

/*INADDR_ANY代表本机IP,htonl将其转换为网络字节顺序(大端模式)*/

server_address.sin_addr.s_addr = htonl(INADDR_ANY);

server_address.sin_port = htons(9734);

server_len = sizeof(server_address);

/*将端口与套接字绑定*/

bind(server_sockfd, (struct sockaddr *)&server_address, server_len);

/*监听,可接受5个连接请求*/

listen(server_sockfd, 5);

FD_ZERO(&readfds);

FD_SET(server_sockfd, &readfds);

/*等待客户端请求*/

while(1) {

char ch;

int fd;

int nread;

testfds = readfds;

/*服务器在select后等待客户端的请求(服务器阻塞)*/

printf("server waiting\n");

result = select(FD_SETSIZE, &testfds, (fd_set *)0,

(fd_set *)0, (struct timeval *)0);

if (result < 1) {

perror("server");

exit(1);

}

/*轮询,实际程序不使用这种极度耗时的方法*/

for (fd = 0; fd < FD_SETSIZE; fd++) {

if (FD_ISSET(fd, &testfds)) {

if (fd == server_sockfd) {

client_len = sizeof(client_address);

client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address,

&client_len); /*接收客户端连接请求,并返回连接套接字用于收发数据*/

FD_SET(client_sockfd, &readfds); /*需要监视发来请求的客户端*/

printf("adding client on fd %d\n", client_sockfd);

} else { /*客户端发生“状况”*/

ioctl(fd, FIONREAD, &nread);

if (nread == 0) {

close(fd); /*读取不到任何内容,关闭与客户端的连接套接字*/

FD_CLR(fd, &readfds); /*清除客户端套接字描述符,不再对其"关注"*/ printf("removing client on fd %d\n", fd);

} else {

read(fd, &ch, 1);

sleep(5);

printf("serving client on fd %d\n", fd);

ch++;

write(fd, &ch, 1);

}

}

}

}

}

}

例子2

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define MYPORT 1234 // the port users will be connecting to

#define BACKLOG 5 // how many pending connections queue will hold #define BUF_SIZE 200

int fd_A[BACKLOG]; // accepted connection fd

int conn_amount; // current connection amount

void showclient()

{

int i;

printf("client amount: %d\n", conn_amount);

for (i = 0; i < BACKLOG; i++)

{

printf("[%d]:%d ", i, fd_A[i]);

}

printf("\n\n");

}

int main(void)

{

int sock_fd, new_fd; // listen on sock_fd, new connection on new_fd

struct sockaddr_in server_addr; // server address information

struct sockaddr_in client_addr; // connector's address information

socklen_t sin_size;

int yes = 1;

char buf[BUF_SIZE];

int ret;

int i;

if ((sock_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

perror("socket");

exit(1);

}

if (setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {

perror("setsockopt");

exit(1);

}

server_addr.sin_family = AF_INET; // host byte order

server_addr.sin_port = htons(MYPORT); // short, network byte order

server_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP memset(server_addr.sin_zero, '\0', sizeof(server_addr.sin_zero));

if (bind(sock_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1)

{

perror("bind");

exit(1);

}

if (listen(sock_fd, BACKLOG) == -1)

{

perror("listen");

exit(1);

}

printf("listen port %d\n", MYPORT);

fd_set fdsr;

int maxsock;

struct timeval tv;

conn_amount = 0;

sin_size = sizeof(client_addr);

maxsock = sock_fd;

while (1)

{

// initialize file descriptor set

FD_ZERO(&fdsr);

FD_SET(sock_fd, &fdsr);

// timeout setting

https://www.sodocs.net/doc/bb2011634.html,_sec = 30;

https://www.sodocs.net/doc/bb2011634.html,_usec = 0;

// add active connection to fd set

for (i = 0; i < BACKLOG; i++)

{

if (fd_A[i] != 0)

{

FD_SET(fd_A[i], &fdsr);

}

ret = select(maxsock + 1, &fdsr, NULL, NULL, &tv);

if (ret < 0)

{

perror("select");

break;

} else if (ret == 0)

{

printf("timeout\n");

continue;

}

// check every fd in the set

for (i = 0; i < conn_amount; i++)

{

if (FD_ISSET(fd_A[i], &fdsr))

{

ret = recv(fd_A[i], buf, sizeof(buf), 0);

if (ret <= 0)

{ // client close

printf("client[%d] close\n", i);

close(fd_A[i]);

FD_CLR(fd_A[i], &fdsr);

fd_A[i] = 0;

}

else

{ // receive data

if (ret < BUF_SIZE)

memset(&buf[ret], '\0', 1);

printf("client[%d] send:%s\n", i, buf);

}

}

}

// check whether a new connection comes

if (FD_ISSET(sock_fd, &fdsr))

{

new_fd = accept(sock_fd, (struct sockaddr *)&client_addr, &sin_size); if (new_fd <= 0)

{

perror("accept");

continue;

}

// add to fd queue

if (conn_amount < BACKLOG)

{

fd_A[conn_amount++] = new_fd;

printf("new connection client[%d] %s:%d\n", conn_amount, inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); if (new_fd > maxsock)

maxsock = new_fd;

}

else

{

printf("max connections arrive, exit\n");

send(new_fd, "bye", 4, 0);

close(new_fd);

break;

}

}

showclient();

}

// close other connections

for (i = 0; i < BACKLOG; i++)

{

if (fd_A[i] != 0)

{

close(fd_A[i]);

}

}

exit(0);

}

linux定时器详解

Linux内核定时器详解 80X86体系结构上,常用的定时器电路 实时时钟(RTC) RTC内核通过IRQ8上发出周期性的中断,频率在2-8192HZ之间,掉电后依然工作,内核通过访问0x70和0x71 I/O端口访问RTC。 时间戳计时器(TSC) 利用CLK输入引线,接收外部振荡器的时钟信号,该计算器是利用64位的时间戳计时器寄存器来实现额,与可编程间隔定时器传递来的时间测量相比,更为精确。 可编程间隔定时器(PIT) PIT的作用类似于微波炉的闹钟,PIT永远以内核确定的固定频率发出中断,但频率不算高。 CPU本地定时器 利用PIC或者APIC总线的时钟计算。 高精度时间定时器(HPET) 功能比较强大,家机很少用,也不去记了。 ACPI电源管理定时器 它的时钟信号拥有大约为3.58MHZ的固定频率,该设备实际上是一个简单的计数器,为了读取计算器的值,内核需要访问某个I/O端口,需要初始化 定时器的数据结构 利用timer_opts描述定时器 Timer_opts的数据结构 Name :标志定时器员的一个字符串 Mark_offset :记录上一个节拍开始所经过的时间,由时钟中断处理程序调用 Get_offset 返回自上一个节拍开始所经过的时间

Monotonic_clock :返回自内核初始化开始所经过的纳秒数 Delay:等待制定数目的“循环” 定时插补 就好像我们要为1小时35分34秒进行定时,我们不可能用秒表去统计,肯定先使用计算时的表,再用计算分的,最后才用秒表,在80x86架构的定时器也会使用各种定时器去进行定时插补,我们可以通过cur_timer指针来实现。 单处理器系统上的计时体系结构 所有与定时有关的活动都是由IRQ线0上的可编程间隔定时器的中断触发。 初始化阶段 1. 初始化间,time_init()函数被调用来建立计时体系结构 2. 初始化xtime变量(xtime变量存放当前时间和日期,它是一个timespec 类型的数据结构) 3. 初始化wall_to_monotonic变量,它跟xtime是同一类型的,但它存放将加在xtime上的描述和纳秒数,这样即使突发改变xtime也不会受到影响。 4. 看是否支持高精度计时器HPET 5. 调用select_timer()挑选系统中可利用的最好的定时资源,并让 cur_timer变量指向该定时器 6. 调用setup_irq(0,&irq0)来创建与IRQ相应的中断门。 时钟中断处理程序 1. 在xtime_lock顺序锁产生一个write_seqlock()来保护与定时相关的内核变量,这样防止中断让该进程被阻止。 2. 执行cur_timer定时器对象的mark_offset方法(记录上一个节拍开始所经过的时间,由时钟中断处理程序调用) 3. 调用do_timer_interrupt函数,步骤为 a) 使jiffies_64值增1 b) 调用updata_times()函数来更新系统日期和时间。

linux Select函数用法详解

Socket-Select Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如 connect、accept、recv或recvfrom 这样的阻塞程序(所谓阻塞方式block,顾名思义,就是进程或是线程执行到这些函数时必须等待某个事件的发生,如果事件没有发生,进程或线程就被阻塞,函数不能立即返回)。 可是使用Select就可以完成非阻塞(所谓非阻塞方式non-block,就是进程或线程执行此函数时不必非要等待事件的发生,一旦执行肯定返回,以返回值的不同来反映函数的执行情况,如果事件发生则与阻塞方式相同,若事件没有发生则返回一个代码来告知事件未发生,而进程或线程继续执行,所以效率较高)方式工作的程序,它能够监视我们需要监视的文件描述符的变化情况——读写或是异常。下面详细介绍一下。 Select的函数格式: int select(int maxfdp,fd_set *readfds,fd_set *writefds,fd_set *errorfds,struct timeval *timeout); 先说明两个结构体: 第一,struct fd_set可以理解为一个集合,这个集合中存放的是文件描述符(file descriptor),即文件句柄,这可以是我们所说的普通意义的文件,当然Unix下任何设备、管道、FIFO等都是文件形式,全部包括在内,所以毫无疑问一个socket就是一个文件,socket句柄就是一个文件描述符。fd_set集合可以通过一些宏由人为来操作,比如清空集合 FD_ZERO(fd_set *),将一个给定的文件描述符加入集合之中FD_SET(int ,fd_set *),将一个给定的文件描述符从集合中删除FD_CLR(int ,fd_set*),检查集合中指定的文件描述符是否可以读写FD_ISSET(int ,fd_set* )。一会儿举例说明。 第二,struct timeval是一个大家常用的结构,用来代表时间值,有两个成员,一个是秒数,另一个是毫秒数。 具体解释select的参数: int maxfdp是一个整数值,是指集合中所有文件描述符的范围,即所有文件描述符的最大值加1,不能错!在Windows中这个参数的值无所谓,可以设置不正确。 fd_set *readfds是指向fd_set结构的指针,这个集合中应该包括文件描述符,我们是要监视这些文件描述符的读变化的,即我们关心是否可以从这些文件中读取数据了,如果这个集合中有一个文件可读,select就会返回一个大于0的值,表示有文件可读,如果没有可读的文件,则根据timeout参数再判断是否

linux下的时间转换函数

linux下的时间函数 我们在编程中可能会经常用到时间,比如取得系统的时间(获取系统的年、月、日、时、分、秒,星期等),或者是隔一段时间去做某事,那么我们就用到一些时间函数。 linux下存储时间常见的有两种存储方式,一个是从1970年到现在经过了多少秒,一个是用一个结构来分别存储年月日时分秒的。 time_t 这种类型就是用来存储从1970年到现在经过了多少秒,要想更精确一点,可以用结构struct timeval,它精确到微妙。 struct timeval { long tv_sec; /*秒*/ long tv_usec; /*微秒*/ }; 而直接存储年月日的是一个结构: struct tm { int tm_sec; /*秒,正常范围0-59,但允许至61*/ int tm_min; /*分钟,0-59*/ int tm_hour; /*小时,0-23*/ int tm_mday; /*日,即一个月中的第几天,1-31*/ int tm_mon; /*月,从一月算起,0-11*/ int tm_year; /*年,从1900至今已经多少年*/ int tm_wday; /*星期,一周中的第几天,从星期日算起,0-6*/ int tm_yday; /*从今年1月1日到目前的天数,范围0-365*/ int tm_isdst; /*日光节约时间的旗标*/ };

需要特别注意的是,年份是从1900年起至今多少年,而不是直接存储如2008年,月份从0开始的,0表示一月,星期也是从0开始的,0表示星期日,1表示星期一。 下面介绍一下我们常用的时间函数: #include char *asctime(const struct tm* timeptr); 将结构中的信息转换为真实世界的时间,以字符串的形式显示 char *ctime(const time_t *timep); 将timep转换为真是世界的时间,以字符串显示,它和asctime不同就在于传入的参数形式不一样 double difftime(time_t time1, time_t time2); 返回两个时间相差的秒数 int gettimeofday(struct timeval *tv, struct timezone *tz); 返回当前距离1970年的秒数和微妙数,后面的tz是时区,一般不用 struct tm* gmtime(const time_t *timep); 将time_t表示的时间转换为没有经过时区转换的UTC时间,是一个struct tm结构指针 stuct tm* localtime(const time_t *timep); 和gmtime类似,但是它是经过时区转换的时间。 time_t mktime(struct tm* timeptr); 将struct tm结构的时间转换为从1970年至今的秒数 time_t time(time_t *t); 取得从1970年1月1日至今的秒数。 上面是简单的介绍,下面通过实战来看看这些函数的用法: 下载: gettime1.c 1. /*gettime1.c*/ 2. #include 3. int main()

select用法

SELECT命令在全国计算机等级考试二级VFP考试中所占的比重可以说非常大,在笔试考试中可以占8-12分,上机考试中占20-50分,所以我将SELECT命令做如下说明,请大家认真学习. SELECT各短语功能: SELECT 说明查询结果,可以用*来表示所有字段,也可以直接写所要查询的字段名,多个字段名也要用英文的逗号隔开,在分组或计算查询中还可以使用如SUM(),COUNT(),A VG(),MAX(),MIN()这些函数进行运算,还可以在排序后用TOP短语来取查询结果的前几条记录,用AS短语对结果字段重新命名; FROM 说明查询的数据源,一般写表名,多个表名用英文的逗号隔开,也可以对所用到的表进行重新命名(如学生st 将学生表重新命名成st表); WHERE 说明查询条件,一般写条件表达式也就是逻辑表达式; GROUP BY说明分组字段此短语后可跟写HA VING短语用来说明分组后的条件; ORDER BY说明排序字段,可以用ASC(升序)和DESC(降序)来说明排序方式; INTO 说明查询去各,可以用TABLE或DBF(表)、CURSOR(临时表)、ARRAY(数组)三短语中一个来说明查询去向的类型。 考点1 简单查询 1简单查询 简单查询是由SELECT和FROM短语构成的无条件查询,或由SELECT,FROM和WHERE短语构成的条件查询。 2简单的连接查询 连接是关系的基本操作之一,连接查询是一种基于多个关系的查询。 3嵌套查询 嵌套查询所要求的结果出自一个关系,但关系的条件却涉及多个关系。其内层基本上也是一个SELECT-FROM-WHERE查询语句。这种简单嵌套查询,可使用谓词IN或NOT IN 来判断在外层的查询条件中是否包含内层查询的结果。 考点2 特殊运算符号 1 BETWEEN…AND… 含义:该查询的条件是在……范围之内,相当于用AND连接的一个逻辑表达式。 2 LIKE 含义:它是一个字符串匹配运算符,与之搭配使用的通配符包括“*”和“?”。 考点3 排序 使用SQL SELECT可以将查询结果进行排序,排序的短语是ORDER BY。 格式:ORDER BY Order_Item[ASCIDESC][,Order_Item[ASC|DESC]…] 说明:可以按升序(ASC)或降序(DESC)排序,允许按一列或多列排序。 考点4 计算查询 1简单的计算查询 SQL不仅具有一般的检索能力,而且还有计算方式的检索,用于计算检索的函数有:COUNT(计数)、SUM(求和)、A VG(计算平均值)、MAX(求最大值)及MIN(求最小值)。 2分组与计算查询 在SQL SELECT中可以利用GROUP BY子句进行分组计算查询。 格式:GROUP BY GroupColumn[,GroupColumn…][HA VING FilterCondition] 说明:可以按一列或多列分组,还可以用HA VING子句进一步限定分组的条件。它必须跟在GROUP BY子句之后,不可单独使用,与WHERE子句并不矛盾。 考点5 别名和自连接查询

SQL语句 SELECT LIKE like用法详解

SQL语句 SELECT LIKE like用法详解 2009-12-16 13:44 LIKE语句的语法格式是:select * from 表名 where 字段名 like 对应值(子串),它主要是针对字符型字段的,它的作用是在一个字符型字段列中检索包含对应子串的。 假设有一个数据库中有个表table1,在table1中有两个字段,分别是name 和sex二者全是字符型数据。现在我们要在姓名字段中查询以“张”字开头的记录,语句如下: select * from table1 where name like "张*" 如果要查询以“张”结尾的记录,则语句如下: select * from table1 where name like "*张" 这里用到了通配符“*”,可以说,like语句是和通配符分不开的。下面我们就详细介绍一下通配符。 多个字符 * c*c代表cc,cBc,cbc,cabdfec等 它同于DOS命令中的通配符,代表多个字符。 多个字符 % %c%代表agdcagd等 这种方法在很多程序中要用到,主要是查询包含子串的。 特殊字符 a a代表a*a 代替* 单字符 ? b?b代表brb,bFb等 同于DOS命令中的?通配符,代表单个字符 单数字 # k#k代表k1k,k8k,k0k 大致同上,不同的是代只能代表单个数字。 字符范围 - [a-z]代表a到z的26个字母中任意一个 指定一个范围中任意一个 续上

排除 [!字符] [!a-z]代表9,0,%,*等 它只代表单个字符 数字排除 [!数字] [!0-9]代表A,b,C,d等 同上 组合类型 字符[范围类型]字符 cc[!a-d]#代表ccF#等 可以和其它几种方式组合使用 例:假设表table1中有以下记录: name sex 张小明男 李明天男 李a天女 王5五男 王清五男 下面我们来举例说明一下: 查询name字段中包含有“明”字的。 select * from table1 where name like '%明%' 查询name字段中以“李”字开头。 select * from table1 where name like '李*' 查询name字段中含有数字的。 select * from table1 where name like '%[0-9]%' 查询name字段中含有小写字母的。 select * from table1 where name like '%[a-z]%' 查询name字段中不含有数字的。 select * from table1 where name like '%[!0-9]%' 我们着重要说明的是通配符“*”与“%”的区别。 select * from table1 where name like '*明*' select * from table1 where name like '%明%' 大家会看到,前一条语句列出来的是所有的记录,而后一条记录列出来的是name字段中含有“明”的记录,所以说,当我们作字符型字段包含一个子串的查询时最好采用“%”而不用“*”,用“*”的时候只在开头或者只在结尾时,而不能两端全由“*”代替任意字符的情况下。 大家在写sql 语句的时候,如果是 select .. where 类型的语句,有注意到条件的前后顺序吗?我今天做个小实验。 比如查询地址里包含“海口市”及“振兴路” 两个关键字的数据,一般时候可能会用

整理的SQL常用函数

create table test (id int, value varchar(10)) insertinto test values('1','aa') insertinto test values('1','bb') insertinto test values('2','aaa') insertinto test values('2','bbb') insertinto test values('2','ccc') insertinto test values('3','aa') insertinto test values('4','bb') select*from test select id, [values] =stuff((select','+ [values] from test t where id = test.id forxmlpath('')), 1 , 1 ,'') from test groupby id stuff(param1,startIndex,length, param2) 说明:将param1中自startIndex(SQL中都是从1开始,而非0)起,删除length个字符,然后用param2替换删掉的字符。*/

COUNT()函数用于返回一个列内所有非空值的个数,这是一个整型值。 由于COUNT(*)函数会忽略NULL值,所以这个查询的结果是2。 三、SUM()函数 SUM()函数是最常用的聚合函数之一,它的功能很容易理解:和AVG()函数一样,它用于数值数据类型,返回一个列范围内所有非空值的总和。 四、CAST()函数 CAST()函数的参数是一个表达式,它包括用AS关键字分隔的源值和目标数据类型。 以下例子用于将文本字符串'123'转换为整型: SELECT CAST('123' AS int) 返回值是整型值123。 如果试图将一个代表小数的字符串转换为整型值,又会出现什么情况呢? SELECT CAST('123.4' AS int) CAST()函数和CONVERT()函数都不能执行四舍五入或截断操作。由于123.4不能用int数据类型来表示,所以对这个函数调用将产生一个错误。 Server: Msg 245, Level 16, State 1, Line 1 Syntax error converting the varchar value '123.4' to a column of data type int. 在将varchar值'123.4' 转换成数据类型int时失败。 要返回一个合法的数值,就必须使用能处理这个值的数据类型。对于这个例子,存在多个可用的数据类型。如果通过CAST()函数将这个值转换为decimal类型,需要首先定义decimal 值的精度与小数位数。在本例中,精度与小数位数分别为9与2。精度是总的数字位数,包括小数点左边和右边位数的总和。而小数位数是小数点右边的位数。这表示本例能够支持的最大的整数值是9999999,而最小的小数是0.01。 SELECT CAST('123.4' AS decimal(9,2)) decimal数据类型在结果网格中将显示有效小数位:123.40 精度和小数位数的默认值分别是18与0。如果在decimal类型中不提供这两个值,SQL Server 将截断数字的小数部分,而不会产生错误。 SELECT CAST('123.4' AS decimal) 结果是一个整数值:123 五、CONVERT()函数 对于简单类型转换,CONVERT()函数和CAST()函数的功能相同,只是语法不同。 CAST()函数一般更容易使用,其功能也更简单。 CONVERT()函数的优点是可以格式化日期和数值,它需要两个参数:第1个是目标数据类型,第2个是源数据。 CONVERT()函数还具有一些改进的功能,它可以返回经过格式化的字符串值,且可以把日期值格式化成很多形式。有28种预定义的符合各种国际和特殊要求的日期与时间输出格式。 六、STR()函数 这是一个将数字转换为字符串的快捷函数。这个函数有3个参数:数值、总长度和小数位数。如果数字的整数位数和小数位数(要加上小数点占用的一个字符)的总和小于总长度,对结果中左边的字符将用空格填充。在下面第1个例子中,包括小数点在内一共是5个字符。结果

Linux下select函数的使用

select系统调用是用来让我们的程序监视多个文件句柄的状态变化的。程序会停在select这里等待,直到被监视的文件句柄有一个或多个发生了状态改变。关于文件句柄,其实就是一个整数,我们最熟悉的句柄是0、1、2三个,0是 标准输入,1是标准输出,2是标准错误输出。0、1、2是整数表示的,对应的FILE *结构的表示就是stdin、stdout、stderr。 int select(int n,fd_set * readfds,fd_set * writefds,fd_set * exceptfds,struct timeval * timeout); 参数n代表文件描述词加1; 参数readfds、writefds 和exceptfds 称为描述词组,是用来回传该描述词的读,写或例外的状况。 下面的宏提供了处理这三种描述词组的方式: FD_CLR(inr fd,fd_set* set);用来清除描述词组set中相关fd 的位 FD_ISSET(int fd,fd_set *set);用来测试描述词组set中相关fd 的位是否 为真 FD_SET(int fd,fd_set*set);用来设置描述词组set中相关fd的位 FD_ZERO(fd_set *set);用来清除描述词组set的全部位 参数timeout为结构timeval,用来设置select()的等待时间,其结构定义如下: struct timeval { time_t tv_sec; time_t tv_usec; }; (1)如果参数timeout设为NULL,则表示select()一直阻塞,直到有句柄状态变化 (2)如果timeout值为0,则select不阻塞直接返回 (3)如果timeout为某个特定值,则在特定时间内阻塞直到有句柄状态变化,如果这个世间内所有句柄状态都无变化,则超时返回0 select函数执行结果:执行成功则返回文件描述词状态已改变的个数,如果返回0代表在描述词状态改变前已超过timeout时间,没有返回;当有错误发生时则返回-1,错误原因存于errno,此时参数readfds,writefds,exceptfds

[MSSQL] - SELECT语句使用大全

SELECT语句使用大全 虽然 SELECT 语句的完整语法比较复杂,但是大多数 SELECT 语句都描述结果集的四个主要属性 1、结果集中的列的数量和属性。 2、从中检索结果集数据的表,以及这些表之间的所有逻辑关系。 3、为了符合 SELECT 语句的要求,源表中的行所必须达到的条件。不符合条件的行会被忽略。 4、结果集的行的排列顺序。 它的主要子句可归纳如下: SELECT select_list --描述结果集的列 INTO new_table_name --指定使用结果集来创建新表 FROM table_list --包含从中检索到结果集数据的表的列表[返回结果集的对象]。 [ WHERE search_conditions ] --WHERE 子句是一个筛选,它定义了源表中的行要满足 SELECT 语句的要求所必须达到的条件 [ GROUP BY group_by_list ] --根据 group_by_list 列中的值将结果集分成组[ HAVING search_conditions ] --结果集的附加筛选 [ ORDER BY order_list [ ASC | DESC ] ] --结果集的附加筛选 一、使用选择列表 1、使用 *号来选择所有列;使用“[表名|别名]。[字段]”选取特定的列。 2、AS 子句可用来更改结果集列的名称或为派生列分配名称,也可以使用空格代替 如: SELECT Name AS Name1,Name Name2 FROM Product ORDER BY Name ASC 3、使用 DISTINCT 消除重复项 如:select distinct [Year] from A 4、使用 TOP 和 PERCENT 限制结果集数量 TOP ( expression ) [ PERCENT ] [ WITH TIES ] --expression 数量、PERCENT按百分比返回数据、WITH TIES返回排序与最后一行并列的行。 如:获取成绩前三名的同学 select top 3 * from Score order by Num desc --不考虑成绩并列 select top 3 WITH TIES * from Score order by Num desc --可解决成绩并列的问题 5、选择列表中的计算值 选择的列不但可以包括数据表列,还可以包括计算值,这些结果集列被称为派生列。 计算并且包括以下运算: 对数值列或常量使用算术运算符或函数进行的计算和运算。如SUM(),

Oracle数据库Select函数基本用法

1、当使用聚集函数时,SELECT中的列不出现在聚集函数中就必须出现在GROUP BY中,否则会出现语法错误;例如下列语句是非法的: SELECT department_id, COUNT(last_name) FROM employees; SELECT department_id,job_id,COUNT(last_name) FROM employees GROUP BY department_id; 2、where部分不能使用聚集函数,例如下面的查询语句是非法的: SELECT department_id, AVG(salary) FROM employees WHERE AVG(salary) > 8000 GROUP BY department_id; 3、使用HAVING关键字限制分组查询的结果,当语句含有HAVING时,先分组再执行含有聚集函数的语句,最后执行HAVING语句: SELECT department_id, MAX(salary) FROM employees GROUP BY department_id HAVING MAX(salary)>10000 ; 4、分组函数的嵌套,出现两个分组函数嵌套时,必须出现GROUP BY 语句,否则会发生错误,例如: SELECT MAX(AVG(salary)) FROM employees; 5、自然连接的练习;使用别名进行连接查询减少内存占用,提高查询效率,能区别不同表中的相同列; NATURAL JOIN 基于不同表中的相同名字的列,当相同名字的列数据类型不同时,就会返回错误信息。 因为表departments、locations中都含有location_id,故可进行如下自然连接查询: SELECT department_id, department_name,, city FROM departments NATURAL JOIN locations ; 6、当具有相同名称的列数据类型不同时可使用USING关键字;当用多列同时满足条件时,可使用USING关键字只匹配其中的一列。 不能对USING关键字后的列进行限制,如下列语句是错误的: SELECT l.city, d.department_name FROM locations l JOIN departments d USING (location_id) WHERE d.location_id = 1400; 7、ON关键字的练习 SELECT e.employee_id,https://www.sodocs.net/doc/bb2011634.html,st_name,e.department_id,d.department_id, d.location_id FROM employees e JOIN departments d ON (e.department_id = d.department_id);

linux下获取系统时间的方法

linux下获取系统时间的方法 时间:2009-11-11 13:45:04 来源:Linux联盟作者:可以用localtime 函数分别获取年月日时分秒的数值。 Linux下获得系统时间的C语言的实现方法: 1. 可以用localtime 函数分别获取年月日时分秒的数值。 #include //C语言的头文件 #include //C语言的I/O void main() { time_t now; //实例化time_t结构 struct tm *timenow; //实例化tm结构指针 time(&now); //time函数读取现在的时间(国际标准时间非北京时间),然后传值给now timenow = localtime(&now); //localtime函数把从time取得的时间now换算成你电脑中的时间(就是你设置的地区) printf("Local time is %sn",asctime(timenow)); //上句中asctime函数把时间转换成字符,通过printf()函数输出 } 注释:time_t是一个在time.h中定义好的结构体。而tm结构体的原形如下: struct tm { int tm_sec;//seconds 0-61 int tm_min;//minutes 1-59 int tm_hour;//hours 0-23 int tm_mday;//day of the month 1-31 int tm_mon;//months since jan 0-11 int tm_year;//years from 1900 int tm_wday;//days since Sunday, 0-6 int tm_yday;//days since Jan 1, 0-365 int tm_isdst;//Daylight Saving time indicator }; 2. 对某些需要较高精准度的需求,Linux提供了gettimeofday()。

SQL Server select into用法

本文来简单的介绍一下SQL Server数据库的SELECT INTO语句。SELECT INTO语句是SELECT语句中很特别的一个类型。 作用: SELECT INTO 语句从一个表中选取数据,然后把数据插入另一个表中。 SELECT INTO 语句常用于创建表的备份复件或者用于对记录进行存档 这个语句会在数据库中用和你所指定的列类型和标题创建一个新的表。 注意事项: SELECT INTO是一种不需要重写表的脚本即可创建一个表的空拷贝的最佳方法,但这个拷贝不包括索引和触发器。你所要做的就是运行一个WHERE子句中条件为假的SELECT INTO。你让SELEC TINTO产生的表必须是数据库中不存在的,否则就会产生一个错误。使用这个语句时必须遵守几个规则: 一、SELECT INTO是一个无日志记载的过程,所以在成品系统上运行SELECTINTO时必须十分小心,因为不能通过回滚来复原操作。 二、执行SELECT INTO语句的人必须在运行该SELECT INTO的数据库中有创建表的许可。 三、SELECT INTO/BULK COPY数据库选项需要在运行SELECT INTO的数据库中打开。SQL SELECT INTO 语法 您可以把所有的列插入新表: Sql代码 1SELECT * 2INTO new_table_name [IN externaldatabase] 3FROM old_tablename 或者只把希望的列插入新表: Java代码 4SELECT column_name(s) 5INTO new_table_name [IN externaldatabase] 6FROM old_tablename 例子: 下面的例子会制作"Persons" 表的备份复件: 1.从同一个数据库中拷贝表及数据: Sql代码

linux定时器和Jiffies

1.linux HZ Linux核心几个重要跟时间有关的名词或变数,以下将介绍HZ、tick与jiffies。 HZ Linux核心每隔固定周期会发出timer interrupt (IRQ 0),HZ是用来定义每一秒有几次timer interrupts。举例来说,HZ为1000,代表每秒有1000次timer interrupts。 HZ可在编译核心时设定,如下所示(以核心版本 adrian@adrian-desktop:~$ cd /usr/src/linux adrian@adrian-desktop:/usr/src/linux$ make menuconfig Processor type and features ---> Timer frequency (250 HZ) ---> 其中HZ可设定100、250、300或1000。 小实验 观察/proc/interrupt的timer中断次数,并于一秒后再次观察其值。理论上,两者应该相差250左右。 adrian@adrian-desktop:~$ cat /proc/interrupts | grep timer && sleep 1 && cat /proc/interrupts | grep timer 0: 9309306 IO-APIC-edge timer 0: 9309562 IO-APIC-edge timer 上面四个栏位分别为中断号码、CPU中断次数、PIC与装置名称。

要检查系统上HZ的值是什么,就执行命令 cat kernel/.config | grep '^CONFIG_HZ=' 2.Tick Tick是HZ的倒数,意即timer interrupt每发生一次中断的时间。如HZ为250时,tick为4毫秒(millisecond)。 3.Jiffies Jiffies为Linux核心变数(unsigned long),它被用来记录系统自开机以来,已经过了多少tick。每发生一次timer interrupt,Jiffies变数会被加一。值得注意的是,Jiffies于系统开机时,并非初始化成零,而是被设为-300*HZ (arch/i386/kernel/time.c),即代表系统于开机五分钟后,jiffies 便会溢位。那溢位怎么办?事实上,Linux核心定义几个macro(timer_after、time_after_eq、time_before与time_before_eq),即便是溢位,也能借由这几个macro正确地取得jiffies的内容。 另外,80x86架构定义一个与jiffies相关的变数jiffies_64 ,此变数64位元,要等到此变数溢位可能要好几百万年。因此要等到溢位这刻发生应该很难吧。

数据库实验五六七八 select语句的使用

实验五select语句的使用(二) 一、实验目的 掌握select语句的嵌套使用方法,能使用sql server对表作复杂查询。 二、实验准备 复习SELECT语句的较高级格式的使用。 了解库函数在分组查询中的使用规则。 三、实验内容 1、找出与李勇在同一个班级的学生信息; 2、找出所有与学生李勇有相同选修课程的学生信息; 3、找出年龄介于学生李勇和25岁之间的学生信息; 4、找出选修了课程操作系统的学生学号和姓名; 5、找出选修了全部课程的学生姓名。(提示:可找出这样的学生,没有一门课程 是他不选修的)。 6、查询选修了3号课程的学生学号及其成绩,并按成绩的降序排列; 7、查询全体学生信息,要求查询结果按班级号升序排列,同一班级学生按年龄 降序排列; 8、求每个课程号及相应的选课人数; 9、查询选修了3门以上课程的学生学号。

实验六视图操作 一、实验目的 建立视图:只读、检查、行列、连接、计算、分组视图。 查询视图:查询所建视图 更新视图:更新所建视图 删除视图:删除所建视图 二、实验内容 1、建立01312班选修了1号课程的学生视图Stu_01312_1; 2、建立01312班选修了1号课程并且成绩不及格的学生视图Stu_01312_1; 3、建立视图Stu_year,由学生学号、姓名、出生年份组成; 4、查询1983年以后出生的学生姓名; 5、查询01312班选修了1号课程并且成绩不及格的学生的学号、姓名、出生年 份。

实验七完整性约束的实现 一、实验目的 掌握SQL中实现数据完整性的方法,加深理解关系数据模型的三类完整性约束。 了解SQL Server中实体完整性、参照完整性和用户自定义完整性的实现手段。 二|、实验内容 表(一)Student 表(二)course 表(三)class

Linux常用函数查询

1: 系统调用:打开一个文件 函数原型:int open(const char pathname, info flage, /* mdode_t m) 头文件:#include #include #include 参数:flag 1> 下面三个常量只能选用一个: O_RDONLY, O_WRONLY, O_RDWR 2> O_CREAT :如果文件不存在,则创建此文件,选用 个参数时,必须同时指定mode参数 3> O_SYNC :最严格的同步方式,每次write操作在 数据和属性都协议时再返回 2:系统调用:改变文件的所有者 1> 函数原型:int chown(cont char *path, uid_t uid, gid_t gid) ; int fchown(int fd, uid_t uid, gid_t gid) ; int lchown(int fd, uid_t uid, gid_t gid) ; 2> 头文件:#include #include 3> 参数:略 4> 返回值:略 3:系统调用:创建连接 1> 函数原型:int link(const char *existPath, const char *newPath) ; 2> 头文件:#include 3> 参数:existpath :已经存在的文件 newpath :新的文件 4> 返回值:略 4:系统调用:删除一个文件 5> 备注:如果newpath已经存在,则失败 4:系统调用:删除一个文件 1> 函数原型:int unlink(const char *path) ; 2> 头文件:#include 3> 参数:略 4> 返回值:略 5> 备注:调用的函数的结果是使得文件的inode-1,如果i_node=0 则自动删除文件数据区 5:标准函数:重命令函数 1> 函数原型:int rename(const char *oldname, const char *newname) ; 2> 头文件:#include 3> 参数:略 4> 返回值:略 6:系统调用:读连接文件内容函数

select()函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET

select函数用于在非阻塞中,当一个套接字或一组套接字有信号时通知你,系统提供select函数来实现多路复用输入/输出模型,原型: #include sys/time.h> #include unistd.h> int select(int maxfd,fd_set *rdset,fd_set *wrset,fd_set *exset,struct timeval *timeout); 参数maxfd是需要监视的最大的文件描述符值+1;rdset,wrset,exset分别对应于需要检测的可读文件描述符的集合,可写文件描述符的集合及异常文件描述符的集合。struct timeval结构用于描述一段时间长度,如果在这个时间内,需要监视的描述符没有事件发生则函数返回,返回值为0。 fd_set(它比较重要所以先介绍一下)是一组文件描述字(fd)的集合,它用一位来表示一个fd(下面会仔细介绍),对于fd_set类型通过下面四个宏来操作: FD_ZERO(fd_set *fdset);将指定的文件描述符集清空,在对文件描述符集合进行设置前,必须对其进行初始化,如果不清空,由于在系统分配内存空间后,通常并不作清空处理,所以结果是不可知的。 FD_SET(fd_set *fdset);用于在文件描述符集合中增加一个新的文件描述符。 FD_CLR(fd_set *fdset);用于在文件描述符集合中删除一个文件描述符。 FD_ISSET(int fd,fd_set *fdset);用于测试指定的文件描述符是否在该集合中。 过去,一个fd_set通常只能包含<32的fd(文件描述字),因为fd_set其实只用了一个32位矢量来表示fd;现在,UNIX系统通常会在头文件中定义常量FD_SETSIZE,它是数据类型fd_set的描述字数量,其值通常是1024,这样就能表示<1024的fd。根据fd_set的位矢量实现,我们可以重新理解操作fd_set的四个宏: fd_set set; FD_ZERO(&set); FD_SET(0, &set); FD_CLR(4, &set); FD_ISSET(5, &set); ――――――――――――――――――――――――――――――――――――――― 注意fd的最大值必须

Ansys中Select命令使用方法概述

以keypoints的选择为例说明select功能的用法 命令格式:KSEL, Type, Item, Comp, VMIN, VMAX, VINC, KABS 作用:用来选择一系列的关键点或者硬点。 以下分别说明各个参数的意义: Type: 用来表明选择的特性: S ——选择一个新的子集(默认值)。 R ——从当前的子集中再次选择。 A ——另外选取一个子集,增加到当前子集中。 U ——从当前子集中剔出一部分集合。 ALL ——选取所有。 NONE ——不选所有。 INVE ——选择补集(将没有选中的集合选中,交换选择的集合)。 SA TA ——显示当前选择状态。 如果Type是S、R、A或者U,那么以下参数才有效。 Item 识别类型的标志。合法的标志符号将在下表中给出。某些标志符会要求有一个分量的标志符。如果Item = PICK(或者简单的一个“P”),那么将以GUI的方式用鼠标选择内容,并且其余的命令将被忽略。默认和KP命令一样。 Comp Item的分量。下表中列出了合法的分量。 VMIN Item范围的最小值。范围的对象包含关键点号、坐标值、属性号等,与Item 对应即可。分量的名字(参见CM命令)也可以被VMIN所替代此时(VMIN和VMAX将被忽略)。如果Item是MAT、TYPE、REAL或者ESYS,并且VMIN是正值,那么Item的绝对值将用于和选择范围值作比较;如果VMIN是负值,那么就以负值作比较。参看KLIST命令中关于符号属性的讨论。 VMAX Item范围的最大值。默认和VMIN相等。

VINC Item范围的增量值。只用整型的数据范围才有用(比如节点号),默认值为1。VINC不能为负数。 KABS 绝对值键: 0——选择过程中检查值的符号。 1——使用绝对值(不检查符号)。 默认命令: 选取所有关键点。 说明: 选择一系列的关键点或者硬点。例如,要选择编号为1---7的关键点,则可以使用命令KSEL,S,KP,,1,7。如果ALL命令使用的话,那么选择就生效,比如KLIST,ALL。只有以编号形式选中的关键点被使用。数据被冠以“选中”或者“未选中”,但是并没有删除任何的数据。 此命令在任何处理器中都适用。 对于非整数型选择(坐标,计算结果等),Item的范围在“VMIN-容差”和“VMIN+容差”之间。容差的默认值取决于VMIN和VMAX值的大小,如下所示: ●如果VMIN=VMAX,容差Toler=0.005×VMIN。 ●如果VMIN=VMAX=0.0,Toler=1.0E-6。 ●如果VMIN VMAX,容差Toler=1.0e-8×(VMAX-VMIN)。 读者可以参考SELTOL命令来修改容差默认值。 KSEL——合法的标识符和分量符号

相关主题