包含javatimeval的词条
本篇文章给大家谈谈javatimeval,以及对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
- 1、JAVA 下棋限定时间。例如30秒必须下完一步,这个限定时间的类怎么写呢?
- 2、java socket难道不能设置socket timeout吗
- 3、java nio和socket的select epoll有什么区别
- 4、libvirt-java怎么获得虚拟机内存使用率
JAVA 下棋限定时间。例如30秒必须下完一步,这个限定时间的类怎么写呢?
起一个线程,定义一个变量如 int timeVal=30;
在run方法中死循环,对上述变量进行自减操作。然后让线程休眠。
对timeVal进行判断,如果等于0.则终止死循环。即可!
代码结构如下
class TimeThread implements Runnable{
int timeVal=30;
public void run(){
while(true){
timeVal--;
//将时间赋值到swing/awt的界面控件上
if(timeVal==0){
break;
}
Thread.sleep(1000);
}
}
}
java socket难道不能设置socket timeout吗
刚看了下jdk里的代码,通过上面的方式设置的timeout只是保存在java层面的,并且只在调用connect的时候才会把这个超时时间传到jvm里面去创建连接,貌似SO_TIMEOUT是连接超时时间,并不是读数据的超时时间,unix中好像本来是没有SO_TIMEOUT这样的TCP值选项的,但是有SO_SNDTIMEO和SO_RCVTIMEO等TCP选项(但是这两个超时时间在jdk层面没有api来设置),所以比较纳闷,我一直以为SO_TIMEOUT是设置的socket读超时,是我理解有误吗
在SocketInputStream.read中还是把这个timeout传进去了的,
public int read(byte b[], int off, int length) throws IOException {
return read(b, off, length, impl.getTimeout());}
不过又产生一个新的疑问,之前看《unix网络编程》中说过poll系统调用中不要把POLLERR/POLLHUP/POLLNVAL等处理异常的常量在events中进行设置(翻了下书确实是这样说的,见p144),但是我看了jvm中bsd/linux相关代码os_linux.inline.hpp都将POLLERR在events中进行了设置,如下所示
inline int os::timeout(int fd, long timeout) {
julong prevtime,newtime;
struct timeval t;
gettimeofday(t, NULL);
prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000;for(;;) {struct pollfd pfd;
pfd.fd = fd;
pfd.events = POLLIN | POLLERR;
int res = ::poll(pfd, 1, timeout);
if (res == OS_ERR errno == EINTR) {
// On Linux any value 0 means "forever"
if(timeout = 0) {
gettimeofday(t, NULL);
newtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000;
timeout -= newtime - prevtime;
if(timeout = 0)
java nio和socket的select epoll有什么区别
当一个节点和多个节点建立连接时,如何高效的处理多个连接的数据,下面具体分析两者的区别。
select函数
函数原型:int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);
参数介绍:(1)nfds -- fdset集合中最大描述符值加1
(2)fdset -- 一个位数组,其大小限制为_FD_SETSIZE(1024)
位数组的每一位代表的是其对应的描述符是否需要被检查。
(3)readfds -- 读事件文件描述符数组
(4 )writefds -- 写事件文件描述符数组
(5)exceptfds -- 错误事件文件描述符数组
(6)timeout -- 超时事件,该结构被内核修改,其值为超时剩余时间。
对应内核:select对应于内核中的sys_select调用,sys_select首先将第二三四个参数指向的fd_set拷贝到内核,然后对每个被SET的描 述符调用进行poll,并记录在临时结果中(fdset),如果有事件发生,select会将临时结果写到用户空间并返回;当轮询一遍后没有任何事件发生时,如果指定了超时时间,则select会睡眠到超时,睡眠结束后再进行一次轮询,并将临时结果写到用户空间,然后返
2. select/poll特点
传统的select/poll每次调用都会线性扫描全部的集合,导致效率呈现线性下降。
poll的执行分三部分:
(1).将用户传入的pollfd数组拷贝到内核空间,因为拷贝操作和数组长度相关,时间上这是一个O(n)操作
(2).查询每个文件描述符对应设备的状态,如果该设备尚未就绪,则在该设备的等待队列中加入一项并继续查询下一设备的状态。 查询完所有设备后如果没有一个设备就绪,这时则需要挂起当前进程等待,直到设备就绪或者超时。设备就绪后进程被通知继续运行,这时再次遍历所有设备,以查找就绪设备。这一步因为两次遍历所有设备,时间复杂度也是O(n),这里面不包括等待时间
(3). 将获得的数据传送到用户空间并执行释放内存和剥离等待队列等善后工作,向用户空间拷贝数据与剥离等待队列等操作的的时间复杂度同样是O(n)。
3. epoll机制
Linux 2.6内核完全支持epoll。epoll的IO效率不随FD数目增加而线性下降。
要使用epoll只需要这三个系统调用:epoll_create(2), epoll_ctl(2), epoll_wait(2)
epoll用到的所有函数都是在头文件sys/epoll.h中声明的,内核实现中epoll是根据每个fd上面的callback函数实现的。只有"活跃"的socket才会主动的去调用 callback函数,其他idle状态socket则不会。
如果所有的socket基本上都是活跃的---比如一个高速LAN环境,过多使用epoll,效率相比还有稍微的下降。但是一旦使用idle connections模拟WAN环境,epoll的效率就远在select/poll之上了。
3.1 所用到的函数:
(1)、int epoll_create(int size)
该函数生成一个epoll专用的文件描述符,其中的参数是指定生成描述符的最大范围
(2)、int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
用于控制某个文件描述符上的事件,可以注册事件,修改事件,删除事件。
如果调用成功返回0,不成功返回-1
int epoll_ctl{
int epfd,//由 epoll_create 生成的epoll专用的文件描述符
int op, //要进行的操作例如注册事件,可能的取值EPOLL_CTL_ADD 注册、
//EPOLL_CTL_MOD 修改、EPOLL_CTL_DEL 删除
int fd, //关联的文件描述符
struct epoll_event *event//指向epoll_event的指针
}
(3)、int epoll_wait(int
epfd, struct epoll_event *
events,int maxevents, int
timeout)
用于轮询I/O事件的发生,返回发生事件数
int epoll_wait{
int epfd,//由epoll_create 生成的epoll专用的文件描述符
struct epoll_event * events,//用于回传代处理事件的数组
int maxevents,//每次能处理的事件数
int timeout//等待I/O事件发生的超时值
//为0的时候表示马上返回,为-1的时候表示一直等下去,直到有事件
//为任意正整数的时候表示等这么长的时间,如果一直没有事件
//一般如果网络主循环是单独的线程的话,可以用-1来等,这样可以保证一些效率
//如果是和主逻辑在同一个线程的话,则可以用0来保证主循环的效率
}
epoll是为处理大批量句柄而作了改进的poll。
4. epoll的优点:
1支持一个进程打开大数目的socket描述符(FD)
select 最不能忍受的是一个进程所打开的FD是有一定限制的,由FD_SETSIZE设置,默认值是2048。对于那些需要支持的上万连接数目的IM服务器来说显然太少了。这时候可以:
(1) 可以修改这个宏然后重新编译内核,不过资料也同时指出,这样也会带来网络效率的下降
(2) 可以选择多进程的解决方案,不过虽然linux上创建进程的代价比较下,但是仍旧是不可忽视的,所以也不是很完美的方案
epoll没有这样的限制,它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,具体数组可以查看cat /proc/sys/fs/file-max查看,这个数目和系统内存关系很大。
2IO效率不随FD数目增加而线性下降
传统的select/poll另一个致命弱点就是当你拥有一个很大的socket集合,不过由于网络延时,任一时间只有部分的socket是"活跃"的,但是select/poll每次调用都会线性扫描全部的集合,导致效率呈现线性下降。
epoll不存在这个问题,它只会对“活跃”的socket进行操作。
这是因为在内核实现中epoll是根据每个fd上面的callback函数实现的。那么,只有"活跃"的socket才会主动的去调用 callback函数,其他idle状态socket则不会,在这点上,epoll实现了一个"伪"AIO,因为这时候推动力在os内核。在一些 benchmark中,如果所有的socket基本上都是活跃的---比如一个高速LAN环境,epoll并不比select/poll有什么效率,相 反,如果过多使用epoll_ctl,效率相比还有稍微的下降。但是一旦使用idle connections模拟WAN环境,epoll的效率就远在select/poll之上了。
3使用mmap加速内核与用户空间的消息传递这点实际上涉及到epoll的具体实现了。无论是select,poll还是epoll都需要内核把FD消息通知给用户空间,如何避免不必要的内存拷贝就 很重要,在这点上,epoll是通过内核于用户空间mmap同一块内存实现的。而如果你想我一样从2.5内核就关注epoll的话,一定不会忘记手工 mmap这一步的。
4内核微调
这一点其实不算epoll的优点了,而是整个linux的优点。也许你可以怀 疑linux,但是你无法回避linux赋予你微调内核的能力。比如,内核TCP/IP协议栈使用内存池管理sk_buff结构,那么可以在运行 时期动态调整这个内存pool(skb_head_pool)的大小--- 通过echo XXXX/proc/sys/net/core/hot_list_length完成。再比如listen函数的第2个参数(TCP完成3次握手 的数据包队列长度),也可以根据你内存大小动态调整。更甚至在一个数据包面数目巨大但同时每个数据包本身大小却很小的特殊系统上尝试最新的NAPI网 卡驱动架构。
libvirt-java怎么获得虚拟机内存使用率
最近在用Nagios监控Xen PV虚拟机的时候出现了问题,在被监控的服务器上是采用nrpe来采集数据的。但是在进程里无法看到PV虚拟机的进程,虽然可以通过xm top vpsname的方式来获取名为vpsname虚拟机的cpu使用率情况,但是不便于采集数据,通过xm list可以采集到cpu时间,根据CPU时间的差值,可以计算CPU使用率,可是该命令只能root执行,因为该命令可以进行关闭,重启虚拟机等重要操作,所以如果把权限给了nrpe,将可能造成严重的安全问题。
幸好livirt提供了API,所以我打算尝试用API写一个Nagios的插件来满足的我的需求,我的想法就是分别2次获得虚拟机的CPU时间,并分别记录2次取得数据时的系统时间,然后根据差值来计算,在理论上是存在一些误差的。
1.要使用API,首先需要安装libvirt-devel
[root@aikaiyuan ~]# yum -y install libvirt-devel
2.我的代码如下,文件名为vCpu.c
/**
* Program Name: vCpu.c
* Author: steptodream
* Description:A simple plugin to get vps cpu usage
* for nagios(nrpe) by libvirt api
* Compile:gcc -o vCpu vCpu.c -lvirt
*/
#include stdlib.h
#include stdio.h
#include libvirt/libvirt.h
/* define the exit status for nagios */
#define OK 0
#define WARNING 1
#define CRITICAL 2
#define UNKNOWN 3
/* get cpu time of the given name */
double getCpuTime(char *vpsName,virConnectPtr conn) {
virDomainInfo info;
virDomainPtr domain = NULL;
int ret;
/* Find the domain of the given name */
domain = virDomainLookupByName(conn, vpsName);
if (domain == NULL) {
printf("Failed to find the vps called %sn", vpsName);
exit(OK);
}
/* Get the information of the domain */
ret = virDomainGetInfo(domain, info);
virDomainFree(domain);
if (ret 0) {
printf("Failed to get information for %sn", vpsName);
exit(OK);
}
return info.cpuTime;
}
int main(int argc,char * argv[])
{
char *vpsName; /* vps name */
int interval = 1; /* check interval */
double warning; /* warning value */
double critical; /* critical value */
double cpuUsage; /* cpu usage of the vps */
struct timeval startTime; /* time of the first time to get cpu time */
struct timeval endTime; /* time of the second time to get cpu time */
int realTime; /* real interval between two times */
long long startCpuTime; /* cpu time of the first time */
long long endCpuTime; /* cpu time of the second time */
int cpuTime; /* value of startCpuTime - endCpuTime */
char *output; /* output data for nagios */
int ret; /* exit status for nagios */
virConnectPtr conn; /* connection pointer */
switch (argc){
case 5:
interval = atoi(argv[4]);
case 4:
vpsName = argv[1];
warning = atof(argv[2]);
critical = atof(argv[3]);
break;
default:
printf("Usage:vCpu vName warning critical [interval]nn");
return OK;
}
/* connect to local Xen Host */
conn = virConnectOpenReadOnly(NULL);
if (conn == NULL) {
printf("Failed to connect to local Xen Hostn");
return OK;
}
/* get cpu time the first time */
startCpuTime = getCpuTime(vpsName, conn);
/* get start time */
if (gettimeofday(startTime, NULL) == -1) {
printf("Failed to get start timen");
return OK;
}
/* wait for some seconds */
sleep(interval);
/* get cpu time the second time */
endCpuTime = getCpuTime(vpsName, conn);
/* get end time */
if (gettimeofday(endTime, NULL) == -1) {
printf("Failed to get end timen");
return OK;
}
/* colose connection */
virConnectClose(conn);
/* calculate the usage of cpu */
cpuTime = (startCpuTime - endCpuTime) / 1000;
realTime = 1000000 * (startTime.tv_sec - endTime.tv_sec) +
(startTime.tv_usec - endTime.tv_usec);
cpuUsage = cpuTime / (double)(realTime);
/* display cpuUsage by percentage */
cpuUsage *= 100;
/* make output data and exit status for nagios*/
if (cpuUsage critical) {
output = "CRITICAL";
ret = CRITICAL;
} else if (cpuUsage warning){
output = "WARNING";
ret = WARNING;
} else {
output = "OK";
ret = OK;
}
printf("%s CPU:%.2f%|CPU=%.2f",output,cpuUsage,cpuUsage);
return ret;
}
3.编译测试,根据我的需求,我设置了3个必须参数和1个可选参数,分别是虚拟机名称vpsName,警告值warning(百分比值),危急值critical(百分比值)和检查间隔interval(秒)
[root@aikaiyuan ~]# gcc -o vCpu vCpu.c -lvirt
[root@aikaiyuan ~]# ./vCpu vmtest 1 2
OK CPU:0.20%|CPU=0.20
当然了,你同时可以再打开一个终端,用xm top vmtest来获取vmtest的cpu使用率,然后对比一下取值是否接近一致。我们再来看看返回值是否正常,因为Nagios是靠这个来判断服务状态的。
[root@aikaiyuan ~]# echo $?
注意,我的具体要求是检测指定名称的虚拟机的CPU使用率,如果超过了规定的warning或者critical值,就给使用者发邮件,所以在没有得到数据或者程序出错的情况,我都是以正常状态退出程序的。
另外,本人开发经验薄弱,所以代码里难免存在错误和不合理的地方以及不完善的地方(比如参数的合法性检验),仅供参考。
最后,关于代码中时间,我是以微秒(us)为统一单位来计算的,得到的cpu的时间是纳秒(ns),这个在结构体virDomainInfo定义中可以看到:
struct virDomainInfo{
unsigned char state : the running state, one of virDomainState
unsigned long maxMem : the maximum memory in KBytes allowed
unsigned long memory : the memory in KBytes used by the domain
unsigned short nrVirtCpu : the number of virtual CPUs for the domain
unsigned long long cpuTime : the CPU time used in nanoseconds
}
而通过gettimeofday取得存取到timeval结构体里的时间,包含tv_sec(s秒)和tv_usec(us微秒)这2种单位,可以从timeval结构体的定义中看到:
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
关于javatimeval和的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。
发布于:2022-12-28,除非注明,否则均为
原创文章,转载请注明出处。