C ++实现用于线程间通信的邮箱 [英] C++ implementation of a mailbox for inter-thread communication
问题描述
我想知道是否有人以前使用POSIX库实现了一个用于线程间通信的邮箱类。作为参考,我看起来与SystemVerilog中使用的邮箱类似: http://www.asic -world.com/systemverilog/sema_mail_events2.html
I'm wondering if anyone has previously implemented a mailbox class for interthread communication using the POSIX library. For reference, I'm looking similar to mailboxes used in SystemVerilog: http://www.asic-world.com/systemverilog/sema_mail_events2.html
EDIT :
我尝试使用STL队列,pthread条件和互斥体在邮箱。它尝试复制链接中描述的SystemVerilog邮箱的行为:
My attempt at a mailbox using STL queues, pthread conditions, and mutexes. It tries to copy the behavior of the SystemVerilog mailbox described in the link:
#include <cerrno>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <fcntl.h>
#include <pthread.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
using namespace std;
class Mailbox{
private:
pthread_cond_t msg_available; // Message in the mailbox?
pthread_mutex_t queue_mutex; // Mutex for queue control
queue<messageT> messages; // Messages
public:
// Constructor
Mailbox(void){
msg_available = PTHREAD_COND_INITIALIZER;
queue_mutex = PTHREAD_MUTEX_INITIALIZER;
}
// Destructor
~Mailbox(void){
// Nothing to do here
}
// Put a single message into the mailbox
void put(messageT msg){
// Lock down queue
if(pthread_mutex_lock(queue_mutex)){
fprintf(stderr, "Queue Mutex Lock Error\n");
exit(EXIT_FAILURE);
}
// Push message into mailbox
messages.push(msg);
// Signal there is a message in the mailbox
if(pthread_cond_signal(&msg_available)){
fprintf(stderr, "cond error");
exit(EXIT_FAILURE);
}
// Unlock queue
if(pthread_mutex_unlock(queue_mutex)){
fprintf(stderr, "Queue Mutex Unlock Error\n");
exit(EXIT_FAILURE);
}
}
// Try to put a single message into the mailbox
int try_put(messageT msg){
// Try to lock down queue
if(pthread_mutex_trylock(queue_mutex) == 0){
// Push message into mailbox
messages.push(msg);
// Signal there is a message in the mailbox
if(pthread_cond_signal(&msg_available)){
fprintf(stderr, "cond error");
exit(EXIT_FAILURE);
}
// Unlock queue
if(pthread_mutex_unlock(queue_mutex)){
fprintf(stderr, "Queue Mutex Unlock Error\n");
exit(EXIT_FAILURE);
}
return 1;
}
// Otherwise, say mailbox is unavailable
else
return 0;
}
// Get single message from a mailbox
void get(mesageT *msg){
// Lock down queue
if(pthread_mutex_lock(queue_mutex)){
fprintf(stderr, "Queue Mutex Lock Error\n");
exit(EXIT_FAILURE);
}
// Wait for a message to come in
while(messages.empty()){
// Release hold of the lock until another thread
// signals that a message has been placed
if(pthread_cond_wait(&msg_available,&queue_mutex)){
fprintf(stderr, "cond_wait error");
exit(EXIT_FAILURE);
}
}
// Pop of least recent message
*msg = messages.front();
messages.pop();
// Unlock queue
if(pthread_mutex_unlock(queue_mutex)){
fprintf(stderr, "Queue Mutex Unlock Error\n");
exit(EXIT_FAILURE);
}
}
// Try to get single message from a mailbox
int try_get(mesageT *msg){
int mailbox_ready = 1; // Mailbox ready
// Lock down queue
if(pthread_mutex_lock(queue_mutex)){
fprintf(stderr, "Queue Mutex Lock Error\n");
exit(EXIT_FAILURE);
}
// Indicate if mailbox is empty
if(messages.empty())
mailbox_ready = 0
// Otherwise, grab the message
else {
// Pop of least recent message
*msg = messages.front();
messages.pop();
}
// Unlock queue
if(pthread_mutex_unlock(queue_mutex)){
fprintf(stderr, "Queue Mutex Unlock Error\n");
exit(EXIT_FAILURE);
}
return mailbox_ready;
}
// Peek at single message from a mailbox
void peek(mesageT *msg){
// Lock down queue
if(pthread_mutex_lock(queue_mutex)){
fprintf(stderr, "Queue Mutex Lock Error\n");
exit(EXIT_FAILURE);
}
// Wait for a message to come in
while(messages.empty()){
// Release hold of the lock until another thread
// signals that a message has been placed
if(pthread_cond_wait(&msg_available,&queue_mutex)){
fprintf(stderr, "cond_wait error");
exit(EXIT_FAILURE);
}
}
// Peek at most recent message
*msg = messages.front();
// Unlock queue
if(pthread_mutex_unlock(queue_mutex)){
fprintf(stderr, "Queue Mutex Unlock Error\n");
exit(EXIT_FAILURE);
}
}
// Try to peek at single message from a mailbox
int try_peek(mesageT *msg){
int mailbox_ready = 1; // Mailbox ready
// Lock down queue
if(pthread_mutex_lock(queue_mutex)){
fprintf(stderr, "Queue Mutex Lock Error\n");
exit(EXIT_FAILURE);
}
if(messages.empty()) // Indicate if mailbox is empty
mailbox_ready = 0
else // Otherwise, grab the message
*msg = messages.front();
// Unlock queue
if(pthread_mutex_unlock(queue_mutex)){
fprintf(stderr, "Queue Mutex Unlock Error\n");
exit(EXIT_FAILURE);
}
return mailbox_ready;
}
}
推荐答案
线程都在同一个进程中,你应该使用 pthread_mutex
和 pthread_condition_variable
, semaphore
。 Unix信号量允许进程间同步,但是它们在进程内效率较低,并且还具有比互斥体和条件变量更难推理的语义。
If the threads are all in the same process you should use pthread_mutex
and pthread_condition_variable
, not semaphore
. Unix semaphores allow inter-process synchronization, but they are less efficient within a process, and also have semantics that are much harder to reason about than mutexes and condition variables.
在这里是C或C ++中有互斥体和条件变量的一些实现:
Here are a number of implementations with mutexes and condition variables in C or C++:
- 这是在C ++中实现有界缓冲区的正确方法
- http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html
- < a href =http://stackoverflow.com/questions/15278343/c11-thread-safe-queue> C ++ 11线程安全队列
- Is this a correct way to implement a bounded buffer in C++
- http://www.justsoftwaresolutions.co.uk/threading/implementing-a-thread-safe-queue-using-condition-variables.html
- C++11 thread-safe queue
这篇关于C ++实现用于线程间通信的邮箱的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!