Vorrei creare una classe i cui metodi possono essere chiamati da più thread. ma invece di eseguire il metodo nel thread da cui è stato chiamato, dovrebbe eseguirli tutti nella propria thread. Nessun risultato deve essere restituito e non dovrebbe bloccare il thread chiamante.Coda eventi/attività Multithreading C++
Un primo tentativo di implementazione che ho incluso di seguito. I metodi pubblici inseriscono un puntatore e dati di funzione in una coda di lavoro, che viene quindi ripresa dal thread di lavoro. Tuttavia non è particolarmente bello codice e l'aggiunta di nuovi metodi è ingombrante.
Idealmente mi piacerebbe usare questo come una classe base che posso facilmente aggiungere metodi (con un numero variabile di argomenti) con minimo hastle e duplicazione del codice.
Qual è un modo migliore per farlo? C'è qualche codice esistente disponibile che fa qualcosa di simile? Grazie
#include <queue>
using namespace std;
class GThreadObject
{
class event
{
public:
void (GThreadObject::*funcPtr)(void *);
void * data;
};
public:
void functionOne(char * argOne, int argTwo);
private:
void workerThread();
queue<GThreadObject::event*> jobQueue;
void functionOneProxy(void * buffer);
void functionOneInternal(char * argOne, int argTwo);
};
#include <iostream>
#include "GThreadObject.h"
using namespace std;
/* On a continuous loop, reading tasks from queue
* When a new event is received it executes the attached function pointer
* It should block on a condition, but Thread code removed to decrease clutter
*/
void GThreadObject::workerThread()
{
//New Event added, process it
GThreadObject::event * receivedEvent = jobQueue.front();
//Execute the function pointer with the attached data
(*this.*receivedEvent->funcPtr)(receivedEvent->data);
}
/*
* This is the public interface, Can be called from child threads
* Instead of executing the event directly it adds it to a job queue
* Then the workerThread picks it up and executes all tasks on the same thread
*/
void GThreadObject::functionOne(char * argOne, int argTwo)
{
//Malloc an object the size of the function arguments
int argumentSize = sizeof(char*)+sizeof(int);
void * myData = malloc(argumentSize);
//Copy the data passed to this function into the buffer
memcpy(myData, &argOne, argumentSize);
//Create the event and push it on to the queue
GThreadObject::event * myEvent = new event;
myEvent->data = myData;
myEvent->funcPtr = >hreadObject::functionOneProxy;
jobQueue.push(myEvent);
//This would be send a thread condition signal, replaced with a simple call here
this->workerThread();
}
/*
* This handles the actual event
*/
void GThreadObject::functionOneInternal(char * argOne, int argTwo)
{
cout << "We've made it to functionTwo char*:" << argOne << " int:" << argTwo << endl;
//Now do the work
}
/*
* This is the function I would like to remove if possible
* Split the void * buffer into arguments for the internal Function
*/
void GThreadObject::functionOneProxy(void * buffer)
{
char * cBuff = (char*)buffer;
functionOneInternal((char*)*((unsigned int*)cBuff), (int)*(cBuff+sizeof(char*)));
};
int main()
{
GThreadObject myObj;
myObj.functionOne("My Message", 23);
return 0;
}
Stavo cercando il boost :: futures, ma poiché non fa parte di una versione di boost rilasciata, ho dovuto ricorrere al mio ACE fidato :-) – lothar
La libreria dei future farà parte di Boost 1.41. È disponibile anche come parte della mia implementazione della libreria di thread C++ 0x su http://www.stdthread.co.uk –
Grazie, Anthony. Piacere di sentirti :) –