2014-04-22 2 views
0

J'ai donc une application qui est un serveur qui ouvre plusieurs threads qui seront utilisés pour les requêtes de base de données. Dans ma fonction de réception, j'ai testé la sortie pour ma requête que j'ai construite et ça a l'air bien quand je customise l'autrtream, donc je l'ajoute à un vecteur. Je ai ensuite coutume le vecteur et il semble aussi bien. Tout cela est fait dans un verrou de mutex, alors je déverrouille le mutex. Mes threads de base de données sont dans une boucle while qui vérifie si mon vector.size()> 0.ostringstream to vector <String> pour la file d'attente multithread

Le problème que je rencontre est que ma boucle ne s'exécute jamais, car elle ne voit jamais le vecteur> 0 (Lequel devrait-il être parce que j'ai pu le vector.begin cout() et il a bien fonctionné. quelqu'un pourrait-il regarder le code et je me dire s'il y a des problèmes qui pourraient être la cause de ce problème.

#Header 
class CNetworkService : public Service 
{ 
    public: 
CNetworkService(void); 
~CNetworkService(void); 
std::ostringstream query; 
string record; 
std::vector<string> queue; 
string IP; 
unsigned int Port; 
void DBWork(); 
bool SaveLog(string insert); 
    protected: 
virtual void handle(LogicalConnection* pClient, IncomingPacket* pRequest); 
}; 

#Source File 
//In my receive handler 
    mtx.lock(); 
query << var1 << var2; 

queue.push_back(query.str()); 
mtx.unlock(); 
query.clear(); 



//This is the function that the database threads are looping in 
void CNetworkService::DBWork() 
{ 


while(true) 
{ 
mtx.lock(); 
while(queue.size() > 0) 
{ 
    printf("Adding new record \n"); 
    SaveLog(queue.front()); 
    queue.erase(queue.begin()); 

} 
mtx.unlock(); 
    } 
    } 

    //The code in the main thread which launches each thread. StartDBThread does some reporting stuff and then lauches the DBWork function, and I can see that DBWork is getting called. In the original attempt I was trying to launch 4 threads, but for now I have scaled it back to 1 thread in order to test and get a working solution. 
    std::thread threads[1]; 
    // spawn 1 threads: 
    for (int i=0; i<1; ++i) 
    threads[i] = std::thread(StartDBThread, i+1); 

    for (auto& th : threads) th.join(); 
+0

La façon normale d'utiliser des files d'attente sécurisées est d'utiliser des variables de condition. Voir l'exemple suivant: http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html – stefaanv

+1

Si vous voulez vraiment une file d'attente, pourquoi ne pas utiliser ['std: : queue'] (http://en.cppreference.com/w/cpp/container/queue)? –

+0

Merci, je ne savais pas à propos de la file d'attente, mais malheureusement, cette question ne concerne pas les vecteurs de la file d'attente et mon problème persiste. – Uwop

Répondre

0

L'un des problèmes possibles que je pourrais penser est que le mutex est acquis ailleurs dans votre code et CNetworkService::DBWork() n'a jamais obtenu le verrou

Th n'est peut-être pas la cause du problème. Mais vous pouvez l'empêcher en ayant la variable mtx un champ privé de CNetworkService puisqu'il est utilisé pour synchroniser la file d'attente et que vous ne voulez pas qu'elle soit utilisée ailleurs.

Je vous suggère de tester en imprimant quelque chose entre mtx.lock() et while(queue.size() > 0) pour voir si le verrou est en cours d'acquisition.

P.S. est très cher.

+0

Je suis en mesure d'obtenir le verrou dans l'autre thread, le problème est que l'autre thread ne voit jamais la taille de mon vecteur qui monte. J'ai juste essayé de sortir la première valeur de mon vecteur en utilisant cout << queue.front() << endl; et je ne peux pas dans le thread DBWork, dans le verrou mutex. – Uwop

+0

Merci également pour l'astuce sur l'effacement de vecteur, je l'ai changé en pop_back() – Uwop

+0

@ AES256 Vous voulez vous assurer que le thread appelant 'CNetworkService :: DBWork()' ne voit pas la taille monter, ou la queue La condition .size()> 0' n'est jamais exécutée du tout. Cela ressemble au deuxième cas, cela signifie probablement que le 'mtx' est acquis par un autre thread et sans être libéré. Aussi, avez-vous rejoint le thread qui appelle 'CNetworkService :: DBWork()' dans votre thread principal? Ce serait utile si vous collez le code. –