Xenomai 实时线程 select 测试
2016-12-14 16:46
337 查看
Xenomai是linux内核的一个实时开发框架,可生成实时线程,基本能达到硬实时要求。
生成实时线程代码如下
pthread_attr_tsvattr;
pthread_t svtid;
pthread_attr_init(&svattr);
pthread_attr_setdetachstate(&svattr,PTHREAD_CREATE_JOINABLE);
pthread_attr_setinheritsched(&svattr,PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedpolicy(&svattr,SCHED_FIFO);
pthread_attr_setschedparam(&svattr,&svparam);
errno= pthread_create(&svtid, &svattr, &server, NULL);
if(errno)
fail("pthread_create");
Xenomai 进程间通信方式分成Xenomai域内的IPC以及Xenomai域和Linux域之间的IPC,采用RTIPC的方式,给用户空间提供socket接口,实时应用通过调用对应的接口可以避免切换到Linux域而导致实时性降低。
进程间通信用socket接口时,在linux下可采用select进行多路复用,参考代码如下:
FD_ZERO(&rset);
FD_SET(sockfd1,&rset);
FD_SET(sockfd2,&rset);
maxfdp1= max(sockfd1, sockfd2) + 1;
Select(maxfdp1,&rset, NULL, NULL, NULL);
if(FD_ISSET(sockfd1, &rset)) { /*socket1 is readable */
/*do something */
}
if(FD_ISSET(sockfd2, &rset)) { /* socket2is readable */
/*do something */
}
在实时域同样的代码则工作不正常,测试代码如下
structsockaddr_ipc saddr, claddr;
socklen_taddrlen;
charbuf[128];
size_tpoolsz;
intret, s;
fd_setrset;
s= socket(AF_RTIPC, SOCK_DGRAM, IPCPROTO_IDDP);
if(s < 0)
fail("socket");
/*
* Set a local 32k pool for the serverendpoint. Memory needed
* to convey datagrams will be pulled from thispool, instead
* of Xenomai's system pool.
*/
poolsz= 32768; /* bytes */
ret= setsockopt(s, SOL_IDDP, IDDP_POOLSZ,
&poolsz, sizeof(poolsz));
if(ret)
fail("setsockopt");
saddr.sipc_family= AF_RTIPC;
saddr.sipc_port= IDDP_SVPORT;
ret= bind(s, (struct sockaddr *)&saddr, sizeof(saddr));
if(ret)
fail("bind");
for(;;) {
FD_ZERO(&rset);
FD_SET(s,&rset);
ret= select(s + 1, &rset, NULL, NULL, NULL);
if(ret < 0) {
fail("select");
}
/*can not reach here */
addrlen= sizeof(saddr);
ret= recvfrom(s, buf, sizeof(buf), 0,
(struct sockaddr *)&claddr,&addrlen);
if(ret < 0) {
close(s);
fail("recvfrom");
}
rt_printf("%s:received %d bytes, \"%.*s\" from port %d\n",
__FUNCTION__, ret, ret, buf,claddr.sipc_port);
}
并且如果配置实时域socket为非阻塞模式,则返回失败
void setnonblocking(int sock)
{
intopts;
opts=fcntl(sock,F_GETFL);
if(opts<0)
{
perror("fcntl(sock,GETFL)"); /* 返回错误 */
exit(1);
}
opts= opts|O_NONBLOCK;
if(fcntl(sock,F_SETFL,opts)<0)
{
perror("fcntl(sock,SETFL,opts)");
exit(1);
}
}
测试结果:实时域socket使用select无法正常返回,Linux域暂时没发现这个问题
生成实时线程代码如下
pthread_attr_tsvattr;
pthread_t svtid;
pthread_attr_init(&svattr);
pthread_attr_setdetachstate(&svattr,PTHREAD_CREATE_JOINABLE);
pthread_attr_setinheritsched(&svattr,PTHREAD_EXPLICIT_SCHED);
pthread_attr_setschedpolicy(&svattr,SCHED_FIFO);
pthread_attr_setschedparam(&svattr,&svparam);
errno= pthread_create(&svtid, &svattr, &server, NULL);
if(errno)
fail("pthread_create");
Xenomai 进程间通信方式分成Xenomai域内的IPC以及Xenomai域和Linux域之间的IPC,采用RTIPC的方式,给用户空间提供socket接口,实时应用通过调用对应的接口可以避免切换到Linux域而导致实时性降低。
进程间通信用socket接口时,在linux下可采用select进行多路复用,参考代码如下:
FD_ZERO(&rset);
FD_SET(sockfd1,&rset);
FD_SET(sockfd2,&rset);
maxfdp1= max(sockfd1, sockfd2) + 1;
Select(maxfdp1,&rset, NULL, NULL, NULL);
if(FD_ISSET(sockfd1, &rset)) { /*socket1 is readable */
/*do something */
}
if(FD_ISSET(sockfd2, &rset)) { /* socket2is readable */
/*do something */
}
在实时域同样的代码则工作不正常,测试代码如下
structsockaddr_ipc saddr, claddr;
socklen_taddrlen;
charbuf[128];
size_tpoolsz;
intret, s;
fd_setrset;
s= socket(AF_RTIPC, SOCK_DGRAM, IPCPROTO_IDDP);
if(s < 0)
fail("socket");
/*
* Set a local 32k pool for the serverendpoint. Memory needed
* to convey datagrams will be pulled from thispool, instead
* of Xenomai's system pool.
*/
poolsz= 32768; /* bytes */
ret= setsockopt(s, SOL_IDDP, IDDP_POOLSZ,
&poolsz, sizeof(poolsz));
if(ret)
fail("setsockopt");
saddr.sipc_family= AF_RTIPC;
saddr.sipc_port= IDDP_SVPORT;
ret= bind(s, (struct sockaddr *)&saddr, sizeof(saddr));
if(ret)
fail("bind");
for(;;) {
FD_ZERO(&rset);
FD_SET(s,&rset);
ret= select(s + 1, &rset, NULL, NULL, NULL);
if(ret < 0) {
fail("select");
}
/*can not reach here */
addrlen= sizeof(saddr);
ret= recvfrom(s, buf, sizeof(buf), 0,
(struct sockaddr *)&claddr,&addrlen);
if(ret < 0) {
close(s);
fail("recvfrom");
}
rt_printf("%s:received %d bytes, \"%.*s\" from port %d\n",
__FUNCTION__, ret, ret, buf,claddr.sipc_port);
}
并且如果配置实时域socket为非阻塞模式,则返回失败
void setnonblocking(int sock)
{
intopts;
opts=fcntl(sock,F_GETFL);
if(opts<0)
{
perror("fcntl(sock,GETFL)"); /* 返回错误 */
exit(1);
}
opts= opts|O_NONBLOCK;
if(fcntl(sock,F_SETFL,opts)<0)
{
perror("fcntl(sock,SETFL,opts)");
exit(1);
}
}
测试结果:实时域socket使用select无法正常返回,Linux域暂时没发现这个问题
相关文章推荐
- Select语句的实用功能:Sql语句中操作Excel - 以下语句已经测试正确
- 嵌入式实时操作系统与测试
- 反病毒实时监控测试样本
- 针对ASP.NET页面实时进行GZIP压缩优化的几款压缩模块的使用简介及应用测试!(附源码)
- 反病毒实时监控测试样本
- 实时进行GZIP压缩优化Asp.Net页面的CompressionModule对Asp.Net Ajax及搜索引擎的兼容性测试!
- 反病毒实时监控测试样本
- 反病毒实时监控测试样本
- 反病毒实时监控测试样本
- 测试timeTask定时执行任务线程,修改系统时间测试的技巧
- Linq to SQL的Select性能测试
- 反病毒实时监控测试样本
- 反病毒实时监控测试样本
- Struts2的select使用及默认值的测试
- 反病毒实时监控测试样本
- 怎样使用mock object测试一个启动新线程的类
- 关于linux线程实时信号的一个问题
- 反病毒实时监控测试样本
- 怎样使用mock object测试一个启动新线程的类
- 反病毒实时监控测试样本