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: 
| 첨부 | 파일 크기 | 
|---|---|
|  qextserialport.tar.gz | 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"); } }시리얼통신을 하신다면 아래 라이버리를 이용하는 것도 괜찮을 껍니다.
시리얼통신을 하신다면 아래 라이버리를 이용하는 것도 괜찮을 껍니다.
약간 수정하시면 괜찮게 사용하실 수 있을겁니다....
답변 감사드립니다...위에서 제시한 방법들로 해 봐야 될거 같네요
답변 감사드립니다...
위에서 제시한 방법들로 해 봐야 될거 같네요...^^
댓글 달기