Before, multithreading some basic things, including thread creation, mutex, semaphore, we have all encapsulated, below to see message queue
We try to minimize the use of the system's own message queue (such as Linux sys/msgqueue), so that the portability is not very strong, we want Message Queuing, message packaging and extraction are used in the standard C + + data structure, of course, you can also use a linked list or FIFO, You have to write a list or FIFO first.
I am lazy, direct use of C + + STL deque, that is, dual-port queue, so reliability is guaranteed, of course, the speed may not be written by their own linked list fast, but it does not matter, the use of dual-port queue can also be based on your own needs to insert data into the queue header or queue end, This is useful in cases where the message has a priority.
The core role of Message Queuing is actually very simple, one or more threads to a queue behind the heap of data, another thread from the front of the queue to take data processing, the basic operation is only two, a hair, a collection, so, we define the message queue base class is:
Class Cmsgqueue {public : cmsgqueue (const char *pname=null); ~cmsgqueue (); Revice data from Message queue virtual bool recvmsg (unsigned int &m_msg_code,void *&p_msg) =0; Send data to Message Queue virtual bool sendmsg (unsigned int m_msg_code,void *p_msg) =0; const char * getName (void) const { return msg_queue_name; } Private: char *msg_queue_name; };
Then remember to add the method to create the message queue in the Coperratingsystemfactory:
Class Coperatingsystemfactory {public : static Coperatingsystem *newoperatingsystem (); Static Ccountingsem *newcountingsem (unsigned int init); Static CMutex *newmutex (const char *pname=null); Static Cmsgqueue *newmsgqueue (const char *pname=null); };
Finally, inherit a clinuxmsgqueue from Cmsgqueue, then implement the Recvmsg and sendmsg, and pay attention to it.
Simple Operation Dual-port FIFO No, we want to be the time to receive the message if there is no message, the thread blocks there waiting for the message until a message arrives before it runs, so we use a semaphore when we receive the message, block it at the semaphore, send a message, and send a semaphore out of the queue.
Second, for the operation of the queue, we want to be atomic, or one is receiving one is in a mess, so the operation of the queue when we use a mutex lock, to ensure the basic atomicity.
corresponding to the specific program is
1. Request a lock for each message queue, a semaphore
Clinuxmsgqueue::clinuxmsgqueue (const char *pname): cmsgqueue (pName) { p_mutex= Coperatingsystemfactory::newmutex ("Msg Mutex"); P_sem=coperatingsystemfactory::newcountingsem (0); }
When receiving a message:
BOOL Clinuxmsgqueue::recvmsg (unsigned int &m_msg_code,void *&p_msg) { bool result; Elements queue_element; P_sem->get (); Blocked by semaphore here, a message arrives before it goes down p_mutex->lock (); Lock, guaranteed atomicity //Operation queue if (M_queue.empty ()) { p_mutex-> UnLock (); return false; } Queue_element = M_queue.front (); M_queue.pop_front (); M_msg_code = Queue_element.msg_code; p_msg = Queue_element.p_message; Operation Queue End P_mutex->unlock ();//unlock return true; }
Sending is also done in a similar way, so that one of the simplest message queues is complete. If we're going to use Message Queuing, it's simple, in main.cpp.
int main () { ///First, create a new message queue cmsgqueue *q=coperatingsystemfactory::newmsgqueue ("B to A Message queue"); New two threads, Testthread and TESTTHREADB are all thread classes inherited from Cthread testthread *a=new testthread ("a"); TESTTHREADB *b=new testthreadb ("B"); Place the message queue in a local variable of two thread entities A->setmsgqueue (q); B->setmsgqueue (q); Start thread a->run (); B->run (); }
When you want to send a message in Mainloop, you only need to call
P_msg_send->sendmsg (Code, (void *) p_msg); Where P_msg_send is a local variable of the B thread and is actually pointing to the newly created message queue Q
GitHub Address:
Https://github.com/wyh267/Cplusplus_Thread_Lib
Written in the following words:
Of course, this code is also very incomplete, the entire code volume is not many lines, here, I just provide a code framework method, as a demo for everyone to reference, if really need to actually use there are many many places need to be modified, GitHub on my code can not be used in the production software actually use, In the actual project, I also realized a no third-party line libraries, more complicated than this, also includes event processing, waiting timeout, message broadcast, message subscription and other modules, and can run in Linux,ecos and other platforms, basically do platform-Independent, But for a variety of reasons I can not publish the code, here is said this framework is only the project midline libraries extracted a very small part of the same, but also just to provide a programming design ideas, the following things hope that we each have their own exploration and improvement, perhaps you looked after, A more powerful and concise framework will be presented.
In addition, the code on GitHub I will continue to improve, will be added to other modules, if you are interested can also be with me to improve, I try not to use the previously implemented line libraries code, to avoid unnecessary trouble.
The above is the C + + multithreaded Framework (3): Message queue content, more relevant content please pay attention to topic.alibabacloud.com (www.php.cn)!