llx2007
凌云志轩
2016-11-17 02:09
采纳率: 89%
浏览 3.0k
已采纳

qt 使用select监听串口时主线程被阻塞

在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?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • devmiao
    devmiao 2016-11-17 06:55
    已采纳
    点赞 评论
  • jklinux
    jklinux 2017-05-07 08:22

    晕,你写的类继承了QThread,创建对象后,run函数不是你调用的,是线程启动后自动调用的,你应调用start函数启动线程。你现在的代码写好了线程,但根本没用上多线程

    点赞 评论
  • llx2007
    凌云志轩 2017-11-22 07:57

    opt.c_cc[VMIN] = 0 //最小时间设置为0
    136 opt.c_cc[VTIME] = 1;//最小字节设置为1

    点赞 评论

相关推荐