在QT中,另起一个线程读串口,使用select监听的,可是为什么主线程也被阻塞了呢?
代码如下:
thread.h
#ifndef DISTANCE_SERIAL_PORT_H
#define DISTANCE_SERIAL_PORT_H
#include <QtCore/QThread>
class Distance_serial_port : public QThread
{
Q_OBJECT
public:
explicit Distance_serial_port(QObject *parent = 0);
void run();
void run_once();
void setTermios(struct termios * pNewtio, int uBaudRate);
void gps_uart_init(int ttyFd,struct termios *oldtio,struct termios *newtio);
};
#endif // DISTANCE_SERIAL_PORT_H
thread.cpp
#include "distance_serial_port.h"
#include <sys/time.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <assert.h>
#include <iostream>
#include <termios.h>
#define BUF_LENGTH 6
#define DEV_NAME "/dev/tty"
Distance_serial_port::Distance_serial_port(QObject *parent) :
QThread()
{}
class CLASS_JULI{
public:
CLASS_JULI(int f = -1):fd(f){ }
~CLASS_JULI()
{
close(fd);
}
int fd;
};
CLASS_JULI dis_port_fds;
void Distance_serial_port::run(){
while(1)
{
try{
run_once();
}
catch(...){
std::cerr<<"distance serial port run throw exception!"<<std::endl;
}
sleep(1);
}
}
void Distance_serial_port::run_once()
{
int ret = 0,i;
unsigned char buf_read[BUF_LENGTH];
fd_set readfd;
struct timeval timeout;
struct termios oldtio, newtio;
dis_port_fds.fd= open(DEV_NAME,O_RDONLY | O_NONBLOCK);
if ((dis_port_fds.fd = open(DEV_NAME, O_RDONLY | O_NONBLOCK)) <= 0) {
std::cout<<" open "<<DEV_NAME<<" faurel!\n"<<std::endl;
return ;
}
else
{
std::cout<<" open "<<DEV_NAME<<" faurel!\n"<<std::endl;
}
gps_uart_init(dis_port_fds.fd,&oldtio,&newtio);
assert(dis_port_fds.fd>0);
while(1)
{
timeout.tv_sec=1;
timeout.tv_usec=0;
FD_ZERO(&readfd);
FD_SET(dis_port_fds.fd,&readfd);
///监控函数
ret=select(dis_port_fds.fd+1,&readfd,NULL,NULL,&timeout);
if(ret == -1) //错误情况
{
std::cout<<"error"<<std::endl ;
}
else if(ret>0) //返回值大于0 有数据到来
{
if(FD_ISSET(dis_port_fds.fd,&readfd))
{
i=read(dis_port_fds.fd,buf_read,BUF_LENGTH);
std::cout<<"----------------------------------------"<<std::endl;
int m = 0;
for(m = 0; m < BUF_LENGTH ; m++)
{
std::cout<<buf_read[m]<<" "<<std::endl;
}
if(buf_read[0] == 'D')
{
char _buf = buf_read[1];
//QBitArray ba(8);
if( (_buf&0x80) == 1 )
{
}
else
{
}
}
break;
}
else //超时情况
{
std::cout<<"time out"<<std::endl;
continue;
}
}
else
{
}
}
}
void Distance_serial_port::setTermios(struct termios * pNewtio, int uBaudRate)
{
/*
*clear struct for new port settings
*/
bzero(pNewtio, sizeof(struct termios));
//8N1
pNewtio->c_cflag = uBaudRate | CS8 | CREAD | CLOCAL;
pNewtio->c_iflag = IGNPAR;
pNewtio->c_oflag = 0;
pNewtio->c_lflag = 0; //non ICANON
}
/*
*设置串口的波特率9600,并刷新使其立即生效
*/
void Distance_serial_port::gps_uart_init(int ttyFd,struct termios *oldtio,struct termios *newtio)
{
tcgetattr(ttyFd, oldtio); /* save current serial port settings */
setTermios(newtio, B115200);
tcflush(ttyFd, TCIFLUSH);
tcsetattr(ttyFd, TCSANOW, newtio);
}
调用方法
dis_serial_prot = new Distance_serial_port();
dis_serial_prot->run();
为什么呢?难道在QT中不能使用select?