Let's say I have 100 worker objects running on 100 separate threads. At some point I'd like to send a triggerSomething signal to the doSomething slot on each of these objects. This is not that difficult. When I create each object I simply connect the triggerSomething signal to the doSomething slot on each object. Then when I emit doSomething all of the worker objects' doSomething slots will be called at the same time:
// Inside some class
QPair<Worker
*,
QThread*> workersAndThreads;
void setupWorkers()
{
workersAndThreads
= new QPair<Worker
*,
QThread*>
[100];
for(int i = 0; i < 100; i++)
{
// Create worker
Worker* worker = new Worker();
workersAndThreads[i].first = worker;
// Create thread
workersAndThreads[i].second = thread;
// Assign worker to the thread
worker->moveToThread(thread);
// Connect the worker
connect(this, SIGNAL(triggerSomething()), worker, SLOT(doSomething()));
// Start the thread (note that the worker isn't doing anything yet).
thread->start();
}
}
void makeAllTheWorkersDoSomethingAtTheSameTime()
{
emit triggerSomething();
}
// Inside some class
QPair<Worker*, QThread*> workersAndThreads;
void setupWorkers()
{
workersAndThreads = new QPair<Worker*, QThread*>[100];
for(int i = 0; i < 100; i++)
{
// Create worker
Worker* worker = new Worker();
workersAndThreads[i].first = worker;
// Create thread
QThread* thread = new QThread();
workersAndThreads[i].second = thread;
// Assign worker to the thread
worker->moveToThread(thread);
// Connect the worker
connect(this, SIGNAL(triggerSomething()), worker, SLOT(doSomething()));
// Start the thread (note that the worker isn't doing anything yet).
thread->start();
}
}
void makeAllTheWorkersDoSomethingAtTheSameTime()
{
emit triggerSomething();
}
To copy to clipboard, switch view to plain text mode
Unfortunately, if I need all of the worker objects to do something at different points in time then this won't work. The triggerSomething signal is hooked up to all of the workers, so there's no way to emit the signal and have it trigger only one of these workers. I can think of two horrible work-arounds for this. First, we could pass an ID in the signal and have each worker object check its ID in the slot to make sure that the signal was really for it. If it was, then it would do something, and if it wasn't then it would disregard the signal. This is very wasteful though since, if there are 100 separate emits (for the 100 objects), there end up being 9,900 unnecessary calls to slots (for the objects whose IDs didn't match the signal). A somewhat better approach which I'm inclined to use right now is this:
void makeASpecificWorkerDoSomething(int indexOfSpecificWorker)
{
// disconnect this object from all previous triggerSomething connections since we don't want to call them all at once.
disconnect(this, SIGNAL(triggerSomething()), 0, 0)
// connect this object to the specific Worker object that we want to call.
Worker* specificWorker = workersAndThreads[indexOfSpecificWorker].first;
connect(this, SIGNAL(triggerSomething()), specificWorker, SLOT(doSomething())
// signal the specific worker object
emit triggerSomething();
}
void makeASpecificWorkerDoSomething(int indexOfSpecificWorker)
{
// disconnect this object from all previous triggerSomething connections since we don't want to call them all at once.
disconnect(this, SIGNAL(triggerSomething()), 0, 0)
// connect this object to the specific Worker object that we want to call.
Worker* specificWorker = workersAndThreads[indexOfSpecificWorker].first;
connect(this, SIGNAL(triggerSomething()), specificWorker, SLOT(doSomething())
// signal the specific worker object
emit triggerSomething();
}
To copy to clipboard, switch view to plain text mode
This accomplishes what I want, but unfortunately it requires a disconnect and a connect every time I want to emit a signal. I'm not sure how costly the connect/disconnect operations are, but I'm inclined to believe that there's a better way to do this.
Any ideas?
Bookmarks