Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <pthread.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <vector>
- #include <string>
- #include <iostream>
- pthread_mutex_t demoMutex = PTHREAD_MUTEX_INITIALIZER;
- pthread_cond_t conditionVariable = PTHREAD_COND_INITIALIZER;
- unsigned int condition = 0;
- struct serverInfo
- {
- unsigned int serverId;
- pthread_t threadId;
- std :: vector <std :: string> queue;
- };
- std :: vector <serverInfo> serverInfoVector;
- void * printHello (void* threadId)
- {
- pthread_t *my_tid = (pthread_t *)threadId;
- pthread_mutex_lock (&demoMutex);
- while (condition == 0)
- pthread_cond_wait (&conditionVariable, &demoMutex);
- unsigned int i = 0;
- char found = false;
- if (serverInfoVector.size () > 0)
- {
- while ((i < serverInfoVector.size ()) && (found == false))
- {
- if (pthread_equal (pthread_self(), serverInfoVector [i].threadId))
- {
- found = true;
- break;
- }
- else
- i++;
- }
- }
- while ((found == true) && (!serverInfoVector [i].queue.empty ()))
- {
- std :: cout << "nThread: " << pthread_self () << ", poped from queue: " << serverInfoVector [i].queue.front () << "n";
- serverInfoVector [i].queue.pop_back ();
- }
- pthread_mutex_unlock (&demoMutex);
- pthread_exit (NULL);
- }
- void checkServerExists (unsigned int serverNumber, std :: string message)
- {
- unsigned int i = 0;
- char found = false;
- pthread_mutex_lock (&demoMutex);
- if (serverInfoVector.size () > 0)
- {
- while ((i < serverInfoVector.size ()) && (found == false))
- {
- if (serverNumber == serverInfoVector [i].serverId)
- {
- found = true;
- break;
- }
- else
- i++;
- }
- }
- if (found == false)
- {
- // This server doesn't exist, so create a thread for it, create a queue for it, push the message in the corresponding queue.
- // Push the server number in the serverNumberArray.
- // Create a thread for it.
- pthread_t newThread;
- int returnValue;
- if ((returnValue = pthread_create (&newThread,
- NULL,
- printHello,
- (void*) &newThread)) != 0)
- {
- printf ("nerror: pthread_create failed with error number %d", returnValue);
- }
- printf ("nIn checkServerExists ()`: thread id %ldn", newThread);
- // Push the message in its queue.
- serverInfo obj;
- obj.serverId = serverNumber;
- obj.threadId = newThread;
- obj.queue.push_back (message);
- serverInfoVector.push_back (obj);
- condition++;
- pthread_cond_signal (&conditionVariable);
- pthread_mutex_unlock (&demoMutex);
- }
- else
- {
- // This server exists, so lookup its thread and queue, push the message in the corresponding queue.
- printf ("nIn else ()`: thread id %ldn", serverInfoVector [i].threadId);
- serverInfoVector [i].queue.push_back (message);
- condition++;
- pthread_cond_signal (&conditionVariable);
- pthread_mutex_unlock (&demoMutex);
- }
- }
- int main ()
- {
- checkServerExists (1, "anisha");
- checkServerExists (2, "kaul");
- checkServerExists (1, "sanjeev");
- checkServerExists (2, "sharma");
- for (unsigned int i = 0; i < serverInfoVector.size (); i++)
- pthread_join (serverInfoVector [i].threadId, NULL);
- return 0;
- }
- extern "C" void* printHello (void* threadId);
- while (condition == 0)
- pthread_cond_wait (&conditionVariable, &demoMutex);
- while (condition == 0)
- {
- // Note I always enclose the statement in {} what happens if pthread_cond_wait()
- // had been a macro? You can never trust all third party libraries so it
- // is better to be safe than struggle to find it with debugger.
- pthread_cond_wait (&conditionVariable, &demoMutex);
- }
- // Once you know it is your decrement.
- --condition;
- void * printHello (void* threadId)
- {
- void* result = NULL;
- try
- {
- result = // Your code here
- }
- catch(std::exception const& e) // Optional
- {
- // Log Exception
- std::cerr << "Exception: " << e.what() << "n";
- }
- catch(...) // MUST have this one.
- {
- // Log Exception
- std::cerr << "Exception: Unknown(...)n";
- }
- return result;
- }
- class MutexLocker
- {
- pthread_mutex_t& mutex;
- MutextLocker(pthread_mutex_t& mutex)
- : mutex(mutex)
- {
- pthread_mutex_lock(&mutex);
- }
- ~MutexLocker()
- {
- pthread_mutex_unlock(&mutex);
- }
- };
- struct serverInfo
- {
- unsigned int serverId;
- pthread_t threadId;
- // Make the queue a pointer
- // So even when this object is copied the queue is unaffected.
- // May want to use a smart pointer or something (needs slightly more thought).
- std::vector<std::string>* queue;
- };
- std::auto_ptr<std::vector<std::string>> queue = new std::vector<std::string>();
- // Pass a pointer to the queue to the thread.
- // Now the thread does not need to know or care about serverInfoVector
- // Which is good because this is being mutated by other people.
- pthread_create(&newThread, NULL, printHello, queue.get()); // Add error code
- if (/* Everything OK */)
- {
- serverInfoVector.push_back(serverInfo(id, newThread, queue.release());
- }
- struct serverInfo
- {
- unsigned int serverId;
- pthread_t threadId;
- std :: vector <std :: string> queue;
- // Add this:
- serverInfo(unsigned int serverId, pthread_t threadId, std::string const& message)
- : serverId(serverId),
- , threadId(threadId)
- {
- queue.push_back(message);
- }
- };
- std :: vector <serverInfo> serverInfoVector;
- unsigned int i = 0;
- if (serverInfoVector.size () > 0)
- {
- if (serverInfoVector.size () > 0)
- {
- while ((i < serverInfoVector.size ()) && (found == false))
- {
- if (serverNumber == serverInfoVector [i].serverId)
- {
- found = true;
- break;
- }
- else
- i++;
- }
- }
- // Push the message in its queue.
- serverInfo obj;
- obj.serverId = serverNumber;
- obj.threadId = newThread;
- obj.queue.push_back (message);
- serverInfoVector.push_back (obj);
- serverInfoVector.push_back(serverInfo(serverNumber, newThread, message));
- {
- // STUFF
- condition++;
- pthread_cond_signal (&conditionVariable);
- pthread_mutex_unlock (&demoMutex);
- }
- else
- {
- // STUFF
- condition++;
- pthread_cond_signal (&conditionVariable);
- pthread_mutex_unlock (&demoMutex);
- }
- checkServerExists (1, "anisha");
- checkServerExists (2, "kaul");
- checkServerExists (1, "sanjeev");
- checkServerExists (2, "sharma");
- MultiThreadServer server;
- server.AddJobToThreadWithID (1, "anisha");
- server.AddJobToThreadWithID (2, "kaul");
- server.AddJobToThreadWithID (1, "sanjeev");
- server.AddJobToThreadWithID (2, "sharma");
- for (unsigned int i = 0; i < serverInfoVector.size (); i++)
- pthread_join (serverInfoVector [i].threadId, NULL);
- return 0;
- void myFunc()
- {
- pthread_mutex_lock(mutex)
- // WORK
- pthread_mutex_unlock(mutex);
- }
- void myFunc()
- {
- MutexLocker lock(mutex)
- // WORK
- }
- for (unsigned int i = 0; i < serverInfoVector.size (); i++)
- pthread_join (serverInfoVector [i].threadId, NULL);
- #include <string>
- #include <map>
- #include <list>
- #include <iostream>
- #include <pthread.h>
- class MutextLocker
- {
- pthread_mutex_t& mutex;
- public:
- MutextLocker(pthread_mutex_t& mutex): mutex(mutex)
- {
- pthread_mutex_lock(&mutex);
- }
- ~MutextLocker()
- {
- pthread_mutex_unlock(&mutex);
- }
- };
- class QueInfo
- {
- public:
- QueInfo()
- : noMoreWork(false)
- , threadStarted(false)
- {
- if (pthread_mutex_init(&mutex, NULL) != 0)
- { throw int(1);
- }
- if (pthread_cond_init(&cond, NULL) != 0)
- {
- pthread_mutex_destroy(&mutex);
- throw int(2);
- }
- }
- ~QueInfo()
- {
- pthread_cond_destroy(&cond);
- pthread_mutex_destroy(&mutex);
- }
- bool getWorkItem(std::string& item)
- {
- MutextLocker lock(mutex);
- while ((queue.size() == 0) && (!noMoreWork))
- {
- pthread_cond_wait (&cond, &mutex);
- }
- bool result = false;
- if (queue.size() != 0)
- {
- item = queue.front();
- queue.pop_front();
- result = true;
- }
- return result;
- }
- void addMessage(std::string const& item)
- {
- MutextLocker lock(mutex);
- queue.push_back(item);
- pthread_cond_signal(&cond);
- }
- void finishedAdding()
- {
- MutextLocker lock(mutex);
- noMoreWork = true;
- pthread_cond_signal(&cond);
- }
- // These two are accessed by ServerInfo but
- // never by the thread. This means we do not need
- // to lock on their use. But I am being lazy here
- // leaving them as public members.
- pthread_t threadId; // Being lazy here
- bool threadStarted; // these two are for use by ServerInfo
- private:
- pthread_mutex_t mutex;
- pthread_cond_t cond;
- bool noMoreWork;
- std::list<std::string> queue;
- };
- class ServerInfo
- {
- public:
- ~ServerInfo()
- {
- for (Cont::iterator loop = queue.begin(); loop != queue.end(); ++loop)
- {
- loop->second.finishedAdding();
- void* result;
- pthread_join(loop->second.threadId, &result);
- }
- }
- void checkServerExists(unsigned int serverNumber, std::string const& message);
- private:
- typedef std::map<unsigned int, QueInfo> Cont;
- Cont queue;
- };
- void* printHello(void* data)
- {
- QueInfo* myQueue = reinterpret_cast<QueInfo*>(data);
- std::string workItem;
- while(myQueue->getWorkItem(workItem))
- {
- std::cout << "nThread: " << pthread_self () << ", poped from queue: " << workItem << "n";
- }
- return NULL; // Return NULL on exit.
- }
- void ServerInfo::checkServerExists(unsigned int serverNumber, std::string const& message)
- {
- QueInfo& item = queue[serverNumber]; // If it does not exist it is inserted.
- item.addMessage(message);
- if (!item.threadStarted)
- {
- int returnValue;
- if ((returnValue = pthread_create (&item.threadId,
- NULL,
- printHello,
- reinterpret_cast<void*>(&item))) != 0)
- {
- std::cout << "nerror: pthread_create failed with error number "<< returnValue;
- queue.erase(serverNumber);
- }
- else
- {
- item.threadStarted = true;
- }
- std::cout << "nIn checkServerExists ()`: thread id " << item.threadId << "n";
- }
- else
- {
- std::cout << "nIn else ()`: thread id " << item.threadId << "n";
- }
- }
- int main ()
- {
- ServerInfo server;
- server.checkServerExists (1, "anisha");
- server.checkServerExists (2, "kaul");
- server.checkServerExists (1, "sanjeev");
- server.checkServerExists (2, "sharma");
- // Note ServerInfo destructor will wait for all the threads.
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement