您的位置:

用c++实现信号量操作,让你的多线程程序轻松实现同步

在多线程编程中,线程之间的同步问题是非常重要的。信号量是一种解决线程同步问题的有效机制。本文将介绍如何使用C++实现信号量操作,让你的多线程程序轻松实现同步。在介绍实现方法之前,我们先来了解一下信号量的基本概念。

一、什么是信号量?

信号量是一种基于计数器的同步机制。它通常被用来控制并发进程对共享资源的访问。信号量有两种操作:P操作和V操作。P操作(也叫wait)会试图将信号量的值减1,如果此时信号量值为负数,则当前线程会被阻塞,直到信号量的值变为非负数。V操作(也叫signal)会将信号量值加1,如果此时信号量的值为非正数,则唤醒因等待该信号量而被阻塞的线程。

二、如何使用C++实现信号量?

在C++11标准中,引入了一个新的头文件<semaphore>,该头文件中提供了一个std::semaphore类,用于实现信号量操作。下面是一个使用std::semaphore类实现信号量的示例:

#include <semaphore>
#include <thread>
#include <iostream>

std::semaphore sem(1); // 定义一个初始值为1的信号量

void worker(int id)
{
  std::cout << "Worker " << id << " is waiting." << std::endl;
  sem.acquire(); // 等待信号量
  std::cout << "Worker " << id << " is working." << std::endl;
  std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟工作时间
  std::cout << "Worker " << id << " is done." << std::endl;
  sem.release(); // 释放信号量
}

int main()
{
  std::thread workers[5];
  for (int i = 0; i < 5; ++i) {
    workers[i] = std::thread(worker, i); // 启动5个工作线程
  }
  for (int i = 0; i < 5; ++i) {
    workers[i].join(); // 等待所有工作线程完成
  }
  return 0;
}

在上面的示例中,我们定义了一个名为sem的信号量,它的初始值为1。在worker函数中,首先使用acquire函数等待信号量,然后开始执行工作,最后使用release函数释放信号量。在main函数中,我们启动了5个工作线程,等待它们完成后结束程序。

三、信号量的应用场景

信号量可以用来解决多线程编程中许多常见的同步问题,比如生产者消费者问题、读写锁问题等。下面以生产者消费者问题为例,来演示信号量的应用:

#include <semaphore>
#include <queue>
#include <thread>
#include <iostream>

std::queue<int> data_queue; // 生产者和消费者共享的数据队列
std::semaphore sem_empty(100); // 定义一个初始值为100的信号量,表示队列中可用元素的最大数量
std::semaphore sem_full(0); // 定义一个初始值为0的信号量,表示队列中已有元素的数量

void producer()
{
  for (int i = 0; i < 100; ++i) {
    sem_empty.acquire(); // 等待队列可用空间
    data_queue.push(i); // 生产数据
    sem_full.release(); // 增加队列中已有元素的数量
  }
}

void consumer(int id)
{
  int data;
  for (int i = 0; i < 50; ++i) {
    sem_full.acquire(); // 等待队列非空
    data = data_queue.front(); // 消费数据
    data_queue.pop();
    sem_empty.release(); // 增加队列可用空间
    std::cout << "Consumer " << id << " consume " << data << std::endl;
    std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 模拟消费时间
  }
}

int main()
{
  std::thread prod(producer); // 启动一个生产者线程
  std::thread cons[5];
  for (int i = 0; i < 5; ++i) {
    cons[i] = std::thread(consumer, i); // 启动5个消费者线程
  }
  prod.join();
  for (int i = 0; i < 5; ++i) {
    cons[i].join();
  }
  return 0;
}

生产者消费者问题是多线程编程中经常遇到的一种并发问题。在上面的示例中,我们定义了一个初始值为100的信号量sem_empty,表示队列中可用元素的最大数量;以及一个初始值为0的信号量sem_full,表示队列中已有元素的数量。

producer函数中,我们向共享队列中生产了100个数据,每次生产前使用acquire函数等待队列可用空间,然后生产完数据后使用release函数增加队列中已有元素的数量。

consumer函数中,我们从共享队列中消费了50个数据,每次消费前使用acquire函数等待队列非空,然后消费完数据后使用release函数增加队列可用空间。

main函数中,我们启动了一个生产者线程和五个消费者线程,等待它们完成后结束程序。通过使用信号量的机制,我们成功地实现了生产者和消费者的同步。

用c++实现信号量操作,让你的多线程程序轻松实现同步

2023-05-24
Python Semaphore实现多线程同步

2023-05-10
Java线程同步的实现方法

2023-05-11
发篇java复习笔记(java课程笔记)

2022-11-09
c语言实现信号量,C语言信号

2022-11-27
python线程创建和同步(python多线程同步)

2022-11-12
jsp程序开发学习笔记2,jsp程序设计题库

本文目录一览: 1、《JSP&Servlet学习笔记》pdf下载在线阅读,求百度网盘云资源 2、林信良编著jsp&servlet学习笔记第2版课后答案吗 3、jsp有没有快速掌握的办法呀? 4、要学J

2023-12-08
一个简单的java信号量例子,java 多线程 信号量

2022-11-17
Python多线程通信实现,让你的程序更高效

2023-05-16
java并发编程之线程同步(java多线程同步器)

2022-11-11
C++ pthread实现多线程编程

C++ pthread库是Linux系统下的线程库,可以实现多线程编程。使用C++ pthread库,可以方便地创建和管理多个线程,从而更好地利用CPU资源,提高计算机的运行效率。 一、多线程编程简介

2023-12-08
c语言笔记讲解,c语言程序笔记

2022-11-23
线程同步丶java教程网,java线程同步的几种方法

2022-11-19
python技巧笔记(python自学笔记)

2022-11-12
Joplin Server安装及配置教程 | 实现跨平台笔记

2023-05-16
印象笔记记录java学习(Java成长笔记)

2022-11-12
如何在iOS中使用信号量提高线程同步效率

2023-05-21
onenote linux——你的轻量级笔记应用

2023-05-21
JavaLock实现线程同步的解析

2023-05-11
golang线程同步,golang 异步

2022-11-27