thread루틴에서 변수값 읽어오기...
글쓴이: cdcmp / 작성시간: 금, 2004/10/22 - 2:30오전
안녕하세요....
thread에 대한 질문을 많이 올리는데요....
thread루프에서 배열에 저장된 값을 메인 루프에서 읽어 오니까 어느 정도
읽다가 프로그램이 종료 되어 버립니다....
소스는 다음과 같습니다...
/////thread.cpp///////
#include <iostream>
using namespace std;
#include "thread.h"
FILE *fp1;
extern unsigned char buf[100000];
int cnt = 0;
int i = 0;
Thread::Thread()
{
stopped = false;
}
void Thread::setMessage(const QString &message)
{
messageStr = message;
}
void Thread::run()
{
while (1)
{
buf[cnt] = i;
fp1 =fopen("/home/eunsu/serial/sensor/thread1/data1.txt","a+");
fprintf(fp1,"%d \n",buf[cnt]);
fclose(fp1);
i++;
cnt++;
}
}
void Thread::stop()
{
stopped = true;
}
///////threadform.cpp//////
#include <qlayout.h>
#include <qpushbutton.h>
#include <qgrid.h>
#include "thread.h"
#include "threadform.h"
int cnt1 = 0;
unsigned char buf[100000];
FILE *fp;
ThreadForm::ThreadForm(QWidget *parent, const char *name)
: QDialog(parent, name)
{
setCaption(tr("Threads"));
threadA.setMessage("A");
threadB.setMessage("B");
threadAButton = new QPushButton(tr("Start A"), this);
threadBButton = new QPushButton(tr("Start B"), this);
quitButton = new QPushButton(tr("Quit"), this);
quitButton->setDefault(true);
connect(threadAButton, SIGNAL(clicked()),
this, SLOT(startOrStopThreadA()));
connect(threadBButton, SIGNAL(clicked()),
this, SLOT(startOrStopThreadB()));
connect(quitButton, SIGNAL(clicked()),
this, SLOT(close()));
QHBoxLayout *mainLayout = new QHBoxLayout(this);
mainLayout->setResizeMode(QLayout::Fixed);
mainLayout->setMargin(11);
mainLayout->setSpacing(6);
mainLayout->addWidget(threadAButton);
mainLayout->addWidget(threadBButton);
mainLayout->addWidget(quitButton);
}
void ThreadForm::startOrStopThreadA()
{
if (threadA.running()) {
threadA.stop();
threadAButton->setText(tr("Start A"));
} else {
threadA.start();
Timer1();
threadAButton->setText(tr("Stop A"));
}
}
void ThreadForm::Timer1()
{
Timer = startTimer(1);
}
void ThreadForm::timerEvent( QTimerEvent *e )
{
if(e->timerId() == Timer)
{
fp = fopen("/home/eunsu/serial/sensor/thread1/data.txt","a+");
fprintf(fp,"%d \n",buf[cnt1]);
fclose(fp);
cnt1++;
}
}
void ThreadForm::closeEvent(QCloseEvent *event)
{
threadA.stop();
threadB.stop();
threadA.wait();
threadB.wait();
event->accept();
}
thread 루프에서는 변수 i가 계속 증가하고 증가된 i 값을 배열 buf에
저장을 합니다...
그리고 메인 루프 threadform.cpp에서는 읽어온 배열 buf에 저장된 값을
파일로 저장을 합니다...
그런데 저장된 값들을 보면 0~255까지 저장 되고 다시 0~255까지 저장되어
있더라고요...0에서부터 계속 증가 해야 하는데....
그리고 thread가 계속 돌면서 얼마후 프로그램이 종료 되어 버리는 현상까지
생기고요...
배열 길이를 정의 하는데서 문제가 있는지....
그래서 루프를 돌리다가 중간에 어느 한 선에서 배열 카운트를 다시 0으로
초기화 시키게 됩니다...
그런데 똑같은 현상이...
고수님들 답변 부탁드리겠습니다...^^
File attachments:
| 첨부 | 파일 크기 |
|---|---|
| 48.98 KB |
Forums:


QCustomEvent를 이용하는 것은 어떨까요?굳이 배열로 잡지 않
QCustomEvent를 이용하는 것은 어떨까요?
굳이 배열로 잡지 않아도 될 것 같은데요.
파일여는 루틴은 while(1) 문 바깥에 나와야 하지 않을까요?
여러개의 쓰레드를 구동하신다면 mutex나 다른 것으 이용하여
lock을 걸어주셔야지 데이터의 안전성이 보장됩니다.
다음은 제가 허접하게 서버 /클라이언트 모델 테스트하거라 만듭겁니다.
허접의 극치임을 알아두시길...
#ifndef CONNECTIONTHREAD_H #define CONNECTIONTHREAD_H #pragma pack(2) #include <qthread.h> #include <qvariant.h> class QWidget; class QMutex; class QSocketDevice; class QString; typedef struct _packet { int socket_id; QString name; int age; QString job; QString phone; }Packet; class ConnectionThread : public QThread { // Q_OBJECT public: ConnectionThread(int sock, QWidget *target); virtual ~ConnectionThread(); void run(); void stop(); protected: private: void readClient(); void sendClient(const QString &str); void sendClient(Packet *); QWidget *receiver; QMutex mutex; QSocketDevice *socket; bool stopped; Packet packet; }; #pragma pack() #endif //CONNECTIONTHREAD_H#include "connectionthread.h" #include <qmutex.h> #include <qsocketdevice.h> #include <qevent.h> #include <qapplication.h> #include <qdatastream.h> ConnectionThread::ConnectionThread(int sock, QWidget *target) : receiver(target), stopped(FALSE) { socket = new QSocketDevice(sock,QSocketDevice::Stream); socket->setBlocking(TRUE); socket->setAddressReusable(TRUE); packet.socket_id=-1; packet.name=" "; packet.age=0; packet.job=" "; packet.phone=" "; } ConnectionThread::~ConnectionThread() { } void ConnectionThread::run() { for( ; ; ) { if (stopped) { mutex.lock(); stopped = FALSE; mutex.unlock(); break; } mutex.unlock(); if( socket->isValid() ) { if ( socket->bytesAvailable() ) { #ifdef DEBUG qWarning("Read the client message"); #endif readClient(); } else { #ifdef DEBUG qWarning("No available bytes"); #endif socket->waitForMore(200); } } else return ; } } void ConnectionThread::stop() { mutex.lock(); stopped = TRUE; mutex.unlock(); } void ConnectionThread::readClient() { QByteArray datagram(socket->bytesAvailable()); socket->readBlock(datagram.data(),datagram.size()); QDataStream in(datagram,IO_ReadOnly); in.setVersion(5); packet.socket_id = socket->socket(); in >> packet.name >> packet.age >> packet.job >> packet.phone ; QCustomEvent *event = new QCustomEvent(12345); event->setData(&packet); QApplication::postEvent(receiver, event); sendClient(&packet); } void ConnectionThread::sendClient(const QString &str) { QByteArray ba; QTextOStream out(ba); out << str; int wrote = socket->writeBlock( ba.data(), ba.size() ); while( wrote < (int)ba.size() ) wrote += socket->writeBlock( ba.data() + wrote, ba.size() - wrote); QCustomEvent *event = new QCustomEvent(12346); event->setData(new QString("Write Cient")); QApplication::postEvent(receiver,event); } void ConnectionThread::sendClient(Packet *pack) { QByteArray datagram; QDataStream out(datagram,IO_WriteOnly); out.setVersion(5); out << pack->name << pack->age << pack->job << pack->phone; pack->socket_id = socket->socket(); socket->writeBlock(datagram, datagram.size()); QCustomEvent *event1 = new QCustomEvent(12347); event1->setData(new QString("Write to the client")); QApplication::postEvent(receiver, event1); QCustomEvent *event = new QCustomEvent(12346); event->setData(pack); QApplication::postEvent(receiver, event); }/**************************************************************************** ** ui.h extension file, included from the uic-generated form implementation. ** ** If you want to add, delete, or rename functions or slots, use ** Qt Designer to update this file, preserving your code. ** ** You should not define a constructor or destructor in this file. ** Instead, write your code in functions called init() and destroy(). ** These will automatically be called by the form's constructor and ** destructor. *****************************************************************************/ #include "connectionthread.h" void Server::init() { server = new Ssocket(4242,50,this,NULL,this); listView->addColumn("Socket id"); listView->addColumn("Name"); listView->addColumn("Age"); listView->addColumn("Job"); listView->addColumn("Phone"); listView->clear(); } void Server::customEvent( QCustomEvent *event ) { switch( event->type() ) { case 12345: { Packet *p = (Packet *) event->data(); QString *s = new QString( tr("Read from Client :: name=" + p->name +" age=%1 "+" job=" + p->job + " phone="+p->phone+" id : %2").arg(p->age).arg(p->socket_id)); textEdit->append(*s); new QListViewItem(listView,tr("%1").arg(p->socket_id), p->name,tr( "%2").arg(p->age), p->job, p->phone); delete s; break; } case 12346: { Packet *p = (Packet *) event->data(); QString *s = new QString( tr("Write to Client :: name=" + p->name +" age=%1 "+" job=" + p->job + " phone="+p->phone+" id : %2").arg(p->age).arg(p->socket_id)); textEdit->append(*s); delete s; break; } case 12347: { QString *s = (QString *)event->data(); textEdit->append(*s); delete s; break; } default: qWarning("Unknown custom event type"); } }시리얼통신을 하신다면 아래 라이버리를 이용하는 것도 괜찮을 껍니다.
시리얼통신을 하신다면 아래 라이버리를 이용하는 것도 괜찮을 껍니다.
약간 수정하시면 괜찮게 사용하실 수 있을겁니다....
답변 감사드립니다...위에서 제시한 방법들로 해 봐야 될거 같네요
답변 감사드립니다...
위에서 제시한 방법들로 해 봐야 될거 같네요...^^
댓글 달기