Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Developer
simon_hain
Posts: 16,282
Registered: ‎07-29-2008
My Device: Z10 LE, Z30, Passport

Easy way to process something on a thread?

I did some research before the holidays, and it seems that running something on a thread (or, generally speaking, without blocking the main thread) is a bit more difficult than i am used to (in BB java).

 

What i am looking for is something like this java code, with a simple runnable defined inline.

new Thread(runnable).start()

 

My current Qt code is based on this post:

http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

QThread* thread = new QThread;
DatabaseWorker* worker = new DatabaseWorker();
worker->moveToThread(thread);
connect(worker, SIGNAL(result()), this, SLOT(onDatabaseResult()));
connect(thread, SIGNAL(started()), worker, SLOT(process()));
connect(worker, SIGNAL(finished()), thread, SLOT(quit()));
connect(worker, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();

 

Basically my issue is that i have a fixed worker class, i would like to have something more flexible for operations that take some time, for example sqlite inserts. it's only 500ms, but it still makes the UI a bit slow.

 

----------------------------------------------------------
feel free to press the like button on the right side to thank the user that helped you.
please mark posts as solved if you found a solution.
@SimonHain on twitter
Developer
TobyKaos
Posts: 78
Registered: ‎12-12-2012
My Device: playbook

Re: Easy way to process something on a thread?

Sorry but I use pthread lib to stream sound in native C++ language. Maybe will hope you?
Developer
BGmot
Posts: 1,068
Registered: ‎11-24-2011
My Device: PlayBook

Re: Easy way to process something on a thread?

You can use just simple threading in C. There is nothing that bounds you to QtThread (I think).

Developer
mreed
Posts: 1,041
Registered: ‎07-16-2008
My Device: ಠ_ಠ

Re: Easy way to process something on a thread?

[ Edited ]

This is generally what I do: Use pthread to start another thread, then move back to your object's method.

 

#include <pthread.h>

///////
// .h

void* decoding_thread(void* arg);

class YourClass {
friend void* decoding_thread(void* arg);
private:
void decoding_thread(void);
}

////////
// .cpp
void YourClass::something() { pthread_t pthread; pthread_create(&pthread, 0, &::decoding_thread, this /*YourClass reference*/ ); } void* decoding_thread(void* arg) { YourClass* yourClass = (YourClass*) arg; yourClass->decoding_thread();
return 0; } void YourClass::decoding_thread() {
// do something
}

 

BlackBerry Development Advisor
smcveigh
Posts: 668
Registered: ‎11-29-2011
My Device: developer

Re: Easy way to process something on a thread?

[ Edited ]

a QThread and signals and slots like you have is fine, but if you're worried about ballooning the number of interfaces, maybe consider a single signal for command and a single signal for response if it's a complex API?

 

eg.

QThread* thread = new QThread;
DatabaseWorker* worker = new DatabaseWorker();
worker->moveToThread(thread);
connect(worker, SIGNAL(request(args)), this, SLOT(onRequest(args)));
connect(thread, SIGNAL(response(args)), worker, SLOT(onResponse(args)));
thread->start();

then you could just pass commands to your thread using whatever args you need... be it enums, varargs, strings, etc.

even more interesting would be the ability to pass classes back and forth...  consider:

class CommandResponse {
public:
CommandResponse(CmdType type) : mType(type), mError(EOK) {};
CmdType getType() { return mType; } // used to demux derived classes
int getError() { return mError; }
....
};
class FetchJpeg : public CommandResponse { public: FetchJpeg(char *url, int timeout) : CommandResponse(CMD_FETCHJPEG), mTimeout(timeout), mBuf(NULL) { mUrl=strdup(url); } ~FetchJpeg() { free(mUrl); free(mData); ... } void getBuffer(char **buf, int *size) { *buf = mBuf; *size = mSize; }
.... };

then you could just allocate a FetchJpeg(...) command, emit it via ::request() and then catch the replies on your ::smileysurprised:nResponse() handler and pull the details using response->getBuffer(&buf, &size); and render.

 

Though this is effectively just pushing command multiplexing up one layer into your code, but otherwise is equivalent to defining a ton of signals and slots.

 

Maybe I'm misunderstanding your concern though...

 

Cheers,

Sean

Developer
simon_hain
Posts: 16,282
Registered: ‎07-29-2008
My Device: Z10 LE, Z30, Passport

Re: Easy way to process something on a thread?

I think what i am looking for is something like the java Runnable interface, where i can overwrite the run method with whatever i want to do.

This would be the java code, which can be used (and re-used) for all kind of fire and forget code.

new Thread() {
	public void run() {
		//process blocking code
	}
}.start();

I guess that is just a java design and not reproducable in c++/Qt?

----------------------------------------------------------
feel free to press the like button on the right side to thank the user that helped you.
please mark posts as solved if you found a solution.
@SimonHain on twitter
BlackBerry Development Advisor
smcveigh
Posts: 668
Registered: ‎11-29-2011
My Device: developer

Re: Easy way to process something on a thread?

[ Edited ]

Isn't that just QThread::run() ?

 

void MyThread::run() {
    // calculate Pi to 1-billion digits....
}

 Or alternately, using plain old pthreads:

void *calculate_pi(void* arg) {
    // calculate pi to 1-billion digits
}

pthread_create(&tid, NULL, calculate_pi, NULL);

Or similar to what mreed suggested, but using a static method in your class....

class MyApp {
    static void* threadEntryPoint(void* arg);
    void* myThread();
    pthread_t mTid;
};

// static wrapper for use with pthreads
void* MyApp::threadEntryPoint(void* arg) {
    MyApp* instance = (MyApp*)arg;
    return instance->myThread();
}

void* MyApp::myThread() {
    // whatever blocking code you want...  
}

// start the thread
pthread_create(&mTid, NULL, threadEntryPoint, (void*)this);

Note that starting a pthread with the default pthread_attr_t (NULL) will produce a thread that needs to be joined later.  If you really want a fire-and-forget <tm> function, then make sure to start the thread detached:

pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&mTid, &attr, threadEntryPoint, (void*)this);

 

Cheers,

Sean

 

Developer
simon_hain
Posts: 16,282
Registered: ‎07-29-2008
My Device: Z10 LE, Z30, Passport

Re: Easy way to process something on a thread?


smcveigh wrote:

Isn't that just QThread::run() ?

 


maybe. Could you give me a quick sample that runs

qDebug() << "i am a thread"

on a qthread?

 

and isn't that the "evil" subclassing that you are not supposed to do?

 

keep in mind, i am quite new to the c++/Qt world :smileyhappy:

----------------------------------------------------------
feel free to press the like button on the right side to thank the user that helped you.
please mark posts as solved if you found a solution.
@SimonHain on twitter
BlackBerry Development Advisor
smcveigh
Posts: 668
Registered: ‎11-29-2011
My Device: developer

Re: Easy way to process something on a thread?

[ Edited ]

I don't know why subclassing would be considered evil.. if they didn't want you to do it, they wouldn't have made the ::run() method virtual :smileyhappy:

 

Disclaimer: I haven't used QThreads, so not sure how to start them up, but this seems like the sort of thing you'd want to do...

class MyThread : public QThread {
public:
   MyThread(QObject *parent = 0) : QThread(parent) {}
protected:
   virtual void run();   
};


void MyThread::run() {
   qDebug() << "I am a thread";
   // don't call exec() if you don't want to run the event loop
}

// run that thread...
MyThread thread;
thread.start();  // I assume this is how you start a QThread?

 

The Qt docs show something similar:

http://doc.qt.digia.com/qt/qthread.html

void QThread::run () [virtual protected]

The starting point for the thread. After calling start(), the newly created thread calls this function. The default implementation simply calls exec().

You can reimplemented this function to do other useful work. Returning from this method will end the execution of the thread.

See also start() and wait().

 

Cheers,

Sean

 

 

 

Developer
simon_hain
Posts: 16,282
Registered: ‎07-29-2008
My Device: Z10 LE, Z30, Passport

Re: Easy way to process something on a thread?

that still requires an own class though, isn't there a mechanism to make it simpler?
Martins approach needs only a method, which is quite a bit better, so i'll check that out as soon as i have some time.
----------------------------------------------------------
feel free to press the like button on the right side to thank the user that helped you.
please mark posts as solved if you found a solution.
@SimonHain on twitter