21xrx.com
2024-12-22 23:20:38 Sunday
登录
文章检索 我的文章 写文章
C++信号量示例:爸爸、女儿、儿子、苹果和橘子的互斥实现
2023-07-02 01:37:49 深夜i     --     --
C++ 信号量 爸爸 女儿 儿子 苹果 橘子 互斥实现

信号量是多线程编程中重要的同步机制之一,其可以解决多线程之间的互斥、同步等问题。下面我们利用C++信号量示例来演示父亲、女儿、儿子、苹果和橘子之间的互斥实现。

首先,我们要明确两个概念:生产者和消费者。在这个场景中,父亲、女儿和儿子是消费者,苹果和橘子是生产者。生产者会不断生产苹果和橘子,而消费者会不断消费这些水果。为了让这个过程互斥,我们需要引入信号量来进行控制。

我们首先定义两个信号量:一个是表示有多少个苹果,另一个是表示有多少个橘子。在生产者将水果放入篮子之前,需要先锁住这两个信号量。在消费者消费水果时,也需要先锁住相应的信号量。这样就保证了同一时间只有一个人在篮子中放入或取出水果。

下面是示例代码:


#include <iostream>

#include <thread>

#include <mutex>

#include <semaphore.h>

using namespace std;

const int basket_size = 5; // 篮子能容纳的最大水果个数

int apple_num = 0; // 篮子中苹果的数量

int orange_num = 0; // 篮子中橘子的数量

mutex cout_mutex; // 为了避免输出信息混乱,定义一个互斥锁

sem_t apple_sem; // 申明一个信号量,表示篮子中苹果的数量

sem_t orange_sem; // 申明一个信号量,表示篮子中橘子的数量

void father_put_fruit() // 父亲向篮子中放水果

{

  while (true)

  {

    sem_wait(&apple_sem); // 等待直到篮子中有空位放苹果

    cout_mutex.lock();

    cout << "Father puts an apple into the basket. The basket contains " << ++apple_num << " apple(s) and " << orange_num << " orange(s)." << endl;

    cout_mutex.unlock();

    sem_post(&orange_sem); // 放进一个苹果,则橘子的数量减1

    this_thread::sleep_for(chrono::seconds(1)); // 暂停1秒

  }

}

void daughter_put_fruit() // 女儿向篮子中放水果

{

  while (true)

  {

    sem_wait(&orange_sem); // 等待直到篮子中有空位放橘子

    cout_mutex.lock();

    cout << "Daughter puts an orange into the basket. The basket contains " << apple_num << " apple(s) and " << ++orange_num << " orange(s)." << endl;

    cout_mutex.unlock();

    sem_post(&apple_sem); // 放进一个橘子,则苹果的数量减1

    this_thread::sleep_for(chrono::seconds(1)); // 暂停1秒

  }

}

void son_get_fruit() // 儿子从篮子中拿水果

{

  while (true)

  {

    sem_wait(&apple_sem); // 等待直到篮子中有苹果

    cout_mutex.lock();

    cout << "Son gets an apple from the basket. The basket contains " << --apple_num << " apple(s) and " << orange_num << " orange(s)." << endl;

    cout_mutex.unlock();

    sem_post(&orange_sem); // 把一个苹果取出来,则橘子的数量加1

    this_thread::sleep_for(chrono::seconds(2)); // 暂停2秒

  }

}

int main()

{

  sem_init(&apple_sem, 0, basket_size); // 初始化信号量为篮子的大小

  sem_init(&orange_sem, 0, 0);

  thread father(father_put_fruit);

  thread daughter(daughter_put_fruit);

  thread son(son_get_fruit);

  father.join();

  daughter.join();

  son.join();

  sem_destroy(&apple_sem);

  sem_destroy(&orange_sem);

}

在这段代码中,我们首先定义篮子的大小为5个水果。定义两个互斥锁,一个是为了避免在输出信息时混乱,另一个是为了保证在别的线程操作时,不会造成数据冲突。接着,会定义两个信号量,一个表示篮子中苹果的数量,另一个表示篮子中橘子的数量。这里需要注意的是,初始化的时候,需要把橘子的信号量设置为0,因为一开始篮子中没有橘子。

最后,我们会定义三个线程:父亲、女儿和儿子。每一个线程都会执行对应的操作,当篮子中放不下了,就会阻塞住,等到篮子中有空位时再继续操作。例如,父亲放苹果的时候,因为篮子已经有5个水果了,所以会一直等待,直到篮子中有水果被儿子或女儿取出来。

在这个C++信号量的示例中,我们演示了父亲、女儿、儿子之间对篮子中水果实现互斥和同步。信号量可以实现线程之间的同步和互斥,避免数据冲突,保证程序正常运行。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复
    相似文章