21xrx.com
2025-07-14 12:48:55 Monday
文章检索 我的文章 写文章
实现生产者消费者模式的C++ TCP通信程序
2023-07-05 02:20:54 深夜i     48     0
生产者 消费者 C++ TCP通信 程序

生产者消费者模式是一种常见的并发编程模型,可以有效地解决不同线程之间的协作问题。在基于TCP的客户端和服务器之间进行通信时,生产者消费者模式同样可以用来优化通信的效率和稳定性。本文介绍一种基于C++语言实现生产者消费者模式的TCP通信程序。

实现步骤:

1. 创建生产者线程和消费者线程,并启动它们。

2. 在生产者线程中,创建一个TCP服务器并监听端口。

3. 当客户端连接到服务器时,将其加入到一个队列中。这个队列用来保存客户端的请求,等待消费者线程处理。

4. 在消费者线程中,从队列中取出客户端的请求,进行处理。

5. 处理完客户端请求后,将结果返回给客户端并关闭连接。

6. 当生产者线程退出时,关闭TCP服务器。

7. 当队列为空时,消费者线程等待,直到有请求加入队列。

代码实现:

1. 创建生产者线程和消费者线程,并启动它们。

pthread_t producer, consumer;
pthread_create(&producer, NULL, produce, NULL);
pthread_create(&consumer, NULL, consume, NULL);

2. 在生产者线程中,创建一个TCP服务器并监听端口。

int sockfd = socket(AF_INET, SOCK_STREAM, 0); // 创建TCP套接字
struct sockaddr_in servaddr;
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY); // 监听所有网络接口
servaddr.sin_port = htons(PORT); // 监听指定端口
bind(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); // 绑定套接字和地址
listen(sockfd, 10); // 开始监听,最多连接10个客户端

3. 当客户端连接到服务器时,将其加入到一个队列中。

int connfd = accept(sockfd, (struct sockaddr *) NULL, NULL); // 接受客户端连接请求
pthread_mutex_lock(&mutex);
request_queue.push(connfd); // 将客户端请求加入队列
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond); // 唤醒消费者线程

4. 在消费者线程中,从队列中取出客户端的请求,进行处理。

while (true) {
  pthread_mutex_lock(&mutex);
  while (request_queue.empty()) {
    pthread_cond_wait(&cond, &mutex); // 等待队列非空的条件满足
  }
  int connfd = request_queue.front(); // 取出队列头部的客户端请求
  request_queue.pop(); // 弹出队列头部
  pthread_mutex_unlock(&mutex);
  // 处理客户端请求
  // ...
  close(connfd); // 关闭客户端连接
}

5. 处理完客户端请求后,将结果返回给客户端并关闭连接。

char buffer[MAXLINE] = { 0 };
read(connfd, buffer, MAXLINE); // 读取客户端发送的数据
// 处理客户端请求
// ...
write(connfd, buffer, strlen(buffer)); // 返回结果给客户端
close(connfd); // 关闭客户端连接

6. 当生产者线程退出时,关闭TCP服务器。

close(sockfd);

7. 当队列为空时,消费者线程等待,直到有请求加入队列。

pthread_mutex_lock(&mutex);
while (request_queue.empty()) {
  pthread_cond_wait(&cond, &mutex); // 等待队列非空的条件满足
}
pthread_mutex_unlock(&mutex);

完整代码如下:

  
  

评论区