各位高手,我的串口程序为什么一但关闭串口句柄,就会把线程也一起关闭了呢?

ssbottle 2011-11-14 05:23:16
rt,我做的串口程序,还有个问题就是如果我的串口不是一直有数据接收的话,那么我写入串口的命令就不会有返回值,看上去是那个线程没有运行一样,但是一旦有数据读进去了,然后也就可以写了,到底是啥原因啊?
我的程序如下:下面是线程类,线程类继承QThread

#include <thread.h>
#include <string.h>
//------------public function--------------------
//
void miniThread::msleep(unsigned long msecs)
{
QThread::msleep(msecs);
}
void miniThread::run()
{
qWarning("miniThread::run()%d ", tioFd);
while(!stopped)
{
if (tioWrite)
{
int ret = 0; //如果那个tioRead不是一直在接收数据,在这个如果写命令的话不会进入这个if语句,只有一直接收数据,我在界面类发送的数据才会进入到这里?为啥?

qWarning("miniThread::run:writting, %s, len: %d", buffWrite, qstrlen(buffWrite));
tioWrite = false;
ret = write(tioFd, buffWrite, strlen(buffWrite));
memset(buffWrite, 0, sizeof(buffWrite));
}
if (tioRead)
{
int len = 0;

qWarning("miniThread::run:Reading");
tioRead = false;
memset(buffRead, 0, sizeof(buffRead));
len = read(tioFd, buffRead, 199);
buffRead[len] = 0;
emit finishOper();
}
if (tioFinished)
{
qWarning("miniThread::run:tioFinished");
close(tioFd); //一旦把这个tioFd给关闭了,miniThread线程也会运行~miniThread(),为啥?

}
}
qWarning("miniThread::run:close thread");
exit();

}
void miniThread::setWriteStr(const char* str)
{
strcpy(buffWrite, str);
}
const char* miniThread::getReadStr(void)
{
return buffRead;
}
miniThread::miniThread()
{
tioFd = -1;
tioFinished = false;
qWarning("miniThread::miniThread()");
}
miniThread::~miniThread()
{
qWarning("miniThread::~miniThread()");
stopped = 1;
tioFd = -1;
wait();
}
void miniThread::setRead(bool isRead)
{
tioRead = isRead;
}
void miniThread::setWrite(bool isWrite)
{
tioWrite = isWrite;
}
void miniThread::setStopped(bool isStopped)
{
qWarning("miniThread::setStopped");
stopped = isStopped;
}
void miniThread::setTioFinished(bool isFinished)
{
qWarning("miniThread::setTioFinished");
tioFinished = isFinished;
}
bool miniThread::openComSuccess(int comPort, int rate, int dataBit, int stopBit, int checkBit, int flowControl )
{
int i;

if((tioFd=open_port(comPort))<0){
qWarning("miniThread::openComSuccess:open_port error");
return false;
}
if((i=set_opt(rate,dataBit,checkBit,stopBit, flowControl ))<0){
qWarning("miniThread::openComSuccess:set_opt error");
return false;
}
return true;
}
//-------------------private function--------------
//设置端口的属性的函数
int miniThread::set_opt(int nSpeed,int nBits, char nEvent,int
nStop, int flow){
struct termios newtio,oldtio;
if(tcgetattr(tioFd,&oldtio)!=0)
{
qWarning("miniThread::set_opt:SetupSerial 1");
}
bzero(&newtio,sizeof(newtio));
newtio.c_cflag|=CLOCAL | CREAD;
newtio.c_cflag&=~CSIZE;
newtio.c_cflag&=~CRTSCTS;
/*newtio.c_cflag |=CRTSCTS;*/
switch(flow)
{
case 1:
newtio.c_cflag |= CRTSCTS;
break;
case 2:
newtio.c_cflag |= (IXON|IXOFF|IXANY);
break;
case 3:
break;
}
switch(nBits){
case 7:
newtio.c_cflag|=CS7;
break;
case 8:
newtio.c_cflag|=CS8;
break;
case 6:
newtio.c_cflag |=CS6;
break;
case 5:
newtio.c_cflag |= CS5;
break;
default:
newtio.c_cflag |= CS8;
break;
}
switch(nEvent){
case 1://'o'
newtio.c_cflag |= PARENB;
newtio.c_cflag |= PARODD;
newtio.c_iflag |=(INPCK | ISTRIP);
break;
case 2://'e'
newtio.c_iflag |= (INPCK | ISTRIP);
newtio.c_cflag |=PARENB;
newtio.c_cflag &=~PARODD;
break;
case 0://'n'
newtio.c_cflag &= ~PARENB;
break;
}

switch(nSpeed){
case 9600:
cfsetispeed(&newtio,B9600);
cfsetospeed(&newtio,B9600);
break;
case 38400:
cfsetispeed(&newtio,B38400);
cfsetospeed(&newtio,B38400);
break;
case 460800:
cfsetispeed(&newtio,B460800);
cfsetospeed(&newtio,B460800);
break;
case 115200:
cfsetispeed(&newtio,B115200);
cfsetospeed(&newtio,B115200);
break;
case 921600:
cfsetispeed(&newtio, B921600);
cfsetospeed(&newtio, B921600);
default:
cfsetispeed(&newtio,B115200);
cfsetospeed(&newtio,B115200);
break;
}

if(nStop==0)
newtio.c_cflag&=~CSTOPB;
else if(nStop==1)
newtio.c_cflag|=CSTOPB;

newtio.c_cc[VTIME]=0;
newtio.c_cc[VMIN]=2;

tcflush(tioFd,TCIFLUSH);

if((tcsetattr(tioFd,TCSANOW,&newtio))!=0){
qWarning("miniThread::set_opt:com set error");
return -1;
}
qWarning ("miniThread::set_opt:set done!\n");
return 0;
}
//打开串口的函数。
int miniThread::open_port(int comport){
long int vdisable;
if(comport==1){
tioFd=open("/dev/ttyS0",O_RDWR|O_NOCTTY|O_NDELAY);
if(-1==tioFd){
perror("miniThread::set_opt:Can't Open Serial Port");
return(-1);
}
else qWarning("miniThread::set_opt:open ttyS0.....\n");
}
if(fcntl(tioFd,F_SETFL,0)<0)
printf("fcntl failed!\n");
else
printf("fcntl =%d\n",fcntl(tioFd,F_SETFL,0));
if(isatty(STDIN_FILENO)==0)
printf("standard input is not a terminal device\n");
else
printf("isaty success!\n");
printf("tioFd-open=%d\n",tioFd);
return tioFd;
}


线程类的头文件。

class miniThread:public QWidget, public QThread
{
Q_OBJECT
private:
volatile bool stopped;
volatile bool tioRead;
volatile bool tioWrite;
volatile bool tioFinished;
volatile int tioFd;
char buffRead[200];
char buffWrite[200];
int set_opt(int nSpeed,int nBits, char nEvent,int nStop, int flow );
int open_port(int comport);

signals:
void finishOper();
public:
miniThread();
~miniThread();

virtual void run();
void setRead(bool isRead);
void setWriteStr(const char* str);
const char * getReadStr( void );
void setWrite(bool isWrite);
void setStopped(bool isStopped);
void setTioFinished(bool isFinished);
bool openComSuccess(int comPort, int rate, int dataBit, int stopBit, int checkBit, int flowControl) ;
void msleep(unsigned long msecs);
};


下面是界面类,

void Form1_inherit::writeThread() //这个函数用作写命令,当按钮按下发出的writeThread SLOT ,这个函数就会被执行。
{
char str[200];

memset(str, 0, sizeof(str));
qstrcpy(str, lineEdit1->text().ascii());

qWarning("Form1_inherit::writeThread:%s ", str);
if (qstrlen(str) > 0)
{
if (checkBox_sendnewline->isChecked())
{
strcat(str, "\r\n");
}
qWarning("Form1_inherit::writeThread:%s", str);
miniThr->setWriteStr(str);
miniThr->setWrite(true);
}
}
信号槽注册函数
Form1_inherit::Form1_inherit(QWidget* parent, const char* name, bool modal, WFlags fl):Form1(parent, name, modal, fl)
{
timer = new QTimer(this);
miniThr = new miniThread;
timer->start(200, false);

qWarning("Form1_inherit:Form1_inherit()");

connect(timer, SIGNAL(timeout()), this, SLOT(readThread()));
connect(pushButton_openport, SIGNAL( clicked() ), this, SLOT(initalComPort()));
connect(pushButton_send, SIGNAL( clicked()), this, SLOT(writeThread()));
connect(miniThr, SIGNAL(finishOper()), this, SLOT(display()));
}
...全文
83 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
ssbottle 2011-11-14
  • 打赏
  • 举报
回复
我知道了,haha,因为QThread是继承QWidget的,然后调用的close其实是调用QWidget的close的,所以把他继承QObject就可以了。
ssbottle 2011-11-14
  • 打赏
  • 举报
回复
对了,我是在界面这个线程类把端口打开的,然后在线程类这个类里把端口关上,是不是这个原因啊?

16,215

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧