2011-10-19 14 views
7

रोका गया है मैं पीसी समांतर बंदरगाह से तरंग उत्पन्न करने के लिए एक परीक्षण उपकरण विकसित कर रहा हूं। यह टूल एमएस की समय सटीकता के साथ तरंग के किसी भी पैटर्न को उत्पन्न करने के लिए डिज़ाइन किया गया है, इसलिए मैं तरंग पैटर्न को परिभाषित करने के लिए लुआ स्क्रिप्ट का उपयोग करता हूं, जीयूआई स्क्रिप्ट चलाने के लिए नया QThread शुरू करता है जब उपयोगकर्ता क्लिक [प्रारंभ] बटन करता है। लुआ के लिएनैनोस्ली() लूआ लिपि से कॉल क्यूटी जीयूआई थ्रेड

निम्नलिखित तीन कार्यों सी ++ वैश्विक कार्यों के रूप में लागू किया जाता है:

  • pwrite: समानांतर पोर्ट के लिए डेटा लिखने।
  • msleep: कुछ एमएस (नैनोस्लीप() का उपयोग करके लागू)
  • प्रिंट: लुआ डिफ़ॉल्ट प्रिंट फ़ंक्शन को ओवरराइट करें, यह एक QTextEdit विजेट को संदेश संलग्न करेगा।

जब पिरिट कहा जाता है, लिखित डेटा वैश्विक चर में संग्रहीत होता है, तो GUI को जीयूआई पर समांतर बंदरगाह डेटा को अद्यतन करने के लिए 20ms अंतराल के साथ अद्यतन किया जाता है। (यह 20 एमएमएस अंतराल ताज़ा एक अच्छा डिजाइन नहीं है, लेकिन मुझे पता नहीं चला है कि डेटा बदलते समय जीयूआई अपडेट करने के लिए सिग्नल का उपयोग कैसे करें)।

उपकरण मूल रूप से कार्यात्मक है। वेवफ़ॉर्म आउटपुट में कोई समस्या नहीं है, लेकिन समांतर बंदरगाह डेटा अपडेटिंग में कुछ समस्या है:

जब लूआ कॉल स्लीप करता है, तो GUI थ्रेड बंद हो जाता है, समांतर बंदरगाह डेटा अपडेट केवल मिस्ली समाप्त होने के बाद ही होता है।

तो मेरी प्रश्न हैं:

  1. कैसे नींद विधि लागू करने के लिए इतना है कि यह अद्यतन करने से जीयूआई धागा बंद नहीं होगा?

  2. पिरिट को कैसे कार्यान्वित करें, ताकि जीआईआई लिखित डेटा बदलते समय समानांतर पोर्ट डेटा को अपडेट करने के लिए सिग्नल प्राप्त कर सके? नीचे दिए गए लिंक के रूप में

कार्यक्रम जीयूआई: Program GUI

संबंधित कोड:

/* common.cpp file */ 

int L_MSleep(lua_State* l) 
{ 
    int milisec=0; 
    struct timespec req={0, 0}; 
    time_t sec; 

    milisec=luaL_optint(l,1,0); // obtain parameter 

    if (milisec==0) 
     return 0; 

    sec=(int)(milisec/1000); 

    milisec=milisec-(sec*1000); 
    req.tv_sec=sec; 
    req.tv_nsec=milisec*1000000L; 

    while(nanosleep(&req,&req)==-1) 
     continue; 

    return 1; 
} 


/* LuaRunner.cpp file */ 
LuaRunner::LuaRunner(QObject *parent) : 
    QThread(parent) 
{ 
    runlua = false; 
} 

void LuaRunner::run() 
{ 
    QString err = ""; 

    runlua = true; 
    LUA_RunScript(this->ff, err); 
    runlua = false; 

    if(err != "") 
    { 
     emit errorMessage(err); 
    } 
} 

int LuaRunner::LUA_RunScript(QString ff, QString &err) 
{ 
    L = lua_open(); 
    luaL_openlibs(L); 

    if (luaL_loadfile(L, ff.toAscii()) || lua_pcall(L, 0, 0, 0)) 
    { 
     err = QString(lua_tostring(L, -1)); 
     return -1; 
    } 

    lua_register(L, "ssleep", L_SSleep); 
    lua_register(L, "msleep", L_MSleep); 
    lua_register(L, "pwrite", L_PortWrite); 
    lua_register(L, "print", L_Log); 

    lua_getglobal(L, "dotest"); 
    if (!lua_isfunction(L, -1)) 
    { 
     err = QString("Test function(dotest) should be a function"); 
     return -1; 
    } 

    if(lua_pcall(L, 0, 0, 0)) 
    { 
     err = QString(lua_tostring(L, -1)); 
     return -1; 
    } 

    lua_close(L); 

    return 0; 
} 

उत्तर

0

शायद आप का उपयोग करना चाहिए क्यूटी के msleep के बाद से यह QThread

4

आप द्वारा उपयोग के लिए प्रदान की जाती है समर्पित धागे में अपनी लुआ स्क्रिप्ट को सही ढंग से चलाएं। ऐसा करने का यह सही तरीका है - लगभग। प्रत्येक बार जब आप स्क्रिप्ट को चलाने के लिए चाहते हैं तो आप थ्रेड को पुनरारंभ कर रहे हैं। यह गलत है। आप बिना किसी प्रकार के सिंक्रनाइज़ेशन के LUU थ्रेड से जीयूआई थ्रेड में डेटा तक पहुंच रहे हैं। यह अच्छा नहीं है। क्यूटी संकेतों और स्लॉट के बीच कतारबद्ध कनेक्शन के रूप में इसके लिए एक उत्कृष्ट तंत्र प्रदान करता है। जब सिग्नल-स्लॉट कॉल थ्रेड सीमाओं को पास करते हैं, तो पैरामीटर QEvent में लपेट जाते हैं और लक्ष्य QObject पर असीमित रूप से वितरित हो जाते हैं। प्रत्येक थ्रेड के भीतर, घटना वितरण धारावाहिक है और इस तरह आप डेटा भ्रष्टाचार आदि के बारे में चिंता करने की जरूरत नहीं

यहाँ

यह कैसे किया जा सकता है:

// LUAObject.h 
#include <QObject> 

class LUAObject : public QObject 
{ 
    Q_OBJECT 
public: 
    LUAObject(QObject * parent = 0); 
public slots: 
    void setScript(const QString &); 
    void runScript(); 
    void stop(); 

signals: 
    void hasError(const QString &); 
    void finished(); 
    void hasParallelData(int); 
    void hasMessage(const QString &); 

private: 
    QString script; 
    bool stop; 
} 

// LUAObject.cpp 

// whatever Lua includes you need etc 

LUAObject::LUAObject(QObject* p) : QObject(p) 
{} 

void LUAObject::stop() { stopped = true; }  

void LUAObject::setScript(const QString & scr) 
{ script = scr; } 

int L_PWrite(lua_State* l) 
{ 
    int data = luaL_optint(l, 1, -1); 
    if (data != -1) { 
     // access the parallel port HERE, NOT in the GUI thread! 
     emit hasParallelData(luaL_optint(l, 1, 0)); 
    } 
    return 0; 
} 

// returns a bool - true means we are stopped and should exit 
int L_MSleep(lua_State* l) 
{ 
    int ms = luaL_optint(l, 1, -1); 
    if (ms == -1) return 0; 
    QApplication::processEvents(QEventLoop::WaitForMoreEvents, ms); 
    lua_pushBoolean(l, stopped); // event processing would run the stop() slot call 
    return 1; 
} 

int L_SSleep(lua_State* l) 
{ 
    int secs = luaL_optint(l, 1, -1); 
    if (secs == -1) return 0; 
    QApplication::processEvents(QEventLoop::WaitForMoreEvents, secs*1000); 
    lua_pushBoolean(l, stopped); // event processing would run the stop() slot call 
    return 1; 
} 

int L_Log(lua_State* l) 
{ 
    const char * msg = luaL_optstring(l, 1, 0); 
    if (!msg) return 0; 
    emit hasMessage(msg); 
    return 0; 
} 

class Lua // RAII 
{ 
public: 
    explicit Lua(lua_state * l) : L(l) {} 
    ~Lua() { lua_close(L); } 
    operator lua_state*() const { return L; } 
private: 
    lua_state * L; 
    Q_DISABLE_COPY(LUA) 
}; 

LUAObject::runScript() 
{ 
    stopped = false; 
    Lua L(lua_open()); 
    luaL_openlibs(L); 

    if (luaL_loadbuffer(L, script.toAscii().constData(), script.length(), "script") || lua_pcall(L, 0, 0, 0)) 
    { 
     emit hasError(lua_tostring(L, -1)); 
     return; 
    } 

    lua_register(L, "ssleep", L_SSleep); 
    lua_register(L, "msleep", L_MSleep); 
    lua_register(L, "pwrite", L_PWrite); 
    lua_register(L, "print", L_Log); 

    lua_getglobal(L, "dotest"); 
    if (!lua_isfunction(L, -1)) 
    { 
     emit hasError("Test function(dotest) should be a function"); 
     return; 
    } 

    if(lua_pcall(L, 0, 0, 0)) 
    { 
     emit hasError(lua_tostring(L, -1)); 
     return; 
    } 

    emit finished(); 
} 

// main.cpp 

#include <QApplication> 
#include <QMetaMethod> 
#include "LUAObject.h" 

... 

int main(int argc, char** argv) 
{ 
    QApplication(argc, argv); 

    MainWindow window; 

    ... 
    QThread thread; 
    LUAObject lua; 
    thread.start(QThread::TimeCriticalPriority); 
    lua.moveToThread(&thread); 

    ... 

    // NOTE: you can ONLY connect to LUAObject slots, you CANNOT call them 
    // directly since it runs in a separate thread! 
    connect(&window, SIGNAL(startClicked()), &lua, SLOT(runScript()); 
    connect(&lua, SIGNAL(hasError(QString)), &window, SLOT(luaError(QString))); 

    ... 
    window.show(); 
    int rc = qApp->exec(); 
    QMetaObject::invokeMethod(&lua, SLOT(stop())); // cross-thread slot invocation 
    thread.exit(); 
    thread.wait(); 
    return rc; 
} 

मैं यूआई के कार्यान्वयन छोड़ आपकी कल्पना के लिए। ध्यान दें कि यह अवांछित कोड है। यह सब मुझे पता है कि यह आपके कंप्यूटर को उड़ा सकता है।

संबंधित मुद्दे