linux同步-生产者消费者-线程-互斥锁-条件变量-信号量

这篇博客介绍了如何利用C语言的互斥锁和条件变量来实现高速缓存的管理,以及使用信号量的另一种实现方式。在互斥锁的实现中,通过条件变量协调生产者和消费者线程,确保数据的安全出队和入队。而在信号量的实现中,生产者增加信号量,消费者在信号量为0时等待,有数据时进行消费。两种方法都有效地避免了竞争条件,实现了缓存的同步操作。
摘要由CSDN通过智能技术生成

   学习了C语言技术网,如下是用互斥锁和条件变量实现高速缓存 

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <vector>

using namespace std;

int mesgid=1;  // 消息的记数器。

// 缓存消息的结构体。
struct st_message{
  int  mesgid;
  char message[1024];
} stmesg;



vector<struct st_message> vcache;  // 用vector容器做缓存。

pthread_cond_t cond = PTHREAD_COND_INITIALIZER;      // 声名并初始化条件变量。
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;   // 声名并初始化互斥锁。

// 消费者、出队线程主函数。
void *outcache(void *arg)

{

  struct st_message stmesg;
  while (true)
  {
    pthread_mutex_lock(&mutex);  // 加锁。

    // 如果缓存为空,等待。 // 条件变量虚假唤醒。
   while (vcache.size() == 0) {
      pthread_cond_wait(&cond,&mutex);
    }

    // 从缓存中获取第一条记录,然后删除该记录。
    memcpy(&stmesg,&vcache[0],sizeof(struct st_message)); // 内存拷贝。
    vcache.erase(vcache.begin());

    pthread_mutex_unlock(&mutex);  // 解锁。

    // 以下是处理业务的代码。

    printf("phid=%ld,mesgid=%d\n",pthread_self(),stmesg.mesgid);
    usleep(100);

  }

}

// 生产者、把生产的数据存入缓存。

void incache(int sig)
{
	struct st_message stmesg;
  memset(&stmesg,0,sizeof(struct st_message));

  pthread_mutex_lock(&mutex);  // 加锁。

  // 生产数据,放入缓存。

  stmesg.mesgid=mesgid++; vcache.push_back(stmesg);   // 内存拷贝。
  stmesg.mesgid=mesgid++; vcache.push_back(stmesg);
  stmesg.mesgid=mesgid++; vcache.push_back(stmesg);
  stmesg.mesgid=mesgid++; vcache.push_back(stmesg);
  stmesg.mesgid=mesgid++; vcache.push_back(stmesg);

  pthread_mutex_unlock(&mutex); // 解锁。

  pthread_cond_broadcast(&cond);  // 触发条件,激活全部的线程。

}


int main()
{
  signal(15,incache);  // 接收15的信号,调用生产者函数。

  pthread_t thid1,thid2,thid3;

  pthread_create(&thid1,NULL,outcache,NULL);
  pthread_create(&thid2,NULL,outcache,NULL);
  pthread_create(&thid3,NULL,outcache,NULL);

  pthread_join(thid1,NULL);
  pthread_join(thid2,NULL);
  pthread_join(thid3,NULL);
  return 0;

} 

以下用互斥锁和信号量实现高速缓存:


#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <vector>
#include <semaphore.h>

using namespace std;

int mesgid=1;  // 消息的记数器。

// 缓存消息的结构体。
struct st_message
{
  int  mesgid;
  char message[1024];
} stmesg;

vector<struct st_message> vcache;  // 用vector容器做缓存。

sem_t sem;  // 声明信号量。

pthread_mutex_t mutex;   // 声名并初始化互斥锁。

// 消费者、出队线程主函数。
void *outcache(void *arg)
{
 struct st_message stmesg;
  while (true)
  {
    while (vcache.size() == 0) 
    {
      sem_wait(&sem);  // 如果缓存中没有数据,等待信号
      printf("%ld wait ok.\n",pthread_self());

    }
    pthread_mutex_lock(&mutex);  // 加锁。

    if (vcache.size() == 0) // 判断缓存中是否有数据。
    {
      pthread_mutex_unlock(&mutex);  continue;  // 解锁,continue。
    }

    // 从缓存中获取第一条记录,然后删除该记录。

    memcpy(&stmesg,&vcache[0],sizeof(struct st_message)); 

    vcache.erase(vcache.begin());

    pthread_mutex_unlock(&mutex);  // 解锁。

    // 以下是处理业务的代码。
    printf("phid=%ld,mesgid=%d\n",pthread_self(),stmesg.mesgid);
    usleep(100);

  }
}

// 生产者、把生产的数据存入缓存。

void incache(int sig)

{

  struct st_message stmesg;

  memset(&stmesg,0,sizeof(struct st_message));
  pthread_mutex_lock(&mutex);  // 加锁。

  // 生产数据,放入缓存。

  stmesg.mesgid=mesgid++; vcache.push_back(stmesg);   
  stmesg.mesgid=mesgid++; vcache.push_back(stmesg);   
  stmesg.mesgid=mesgid++; vcache.push_back(stmesg);   
  stmesg.mesgid=mesgid++; vcache.push_back(stmesg);   
  stmesg.mesgid=mesgid++; vcache.push_back(stmesg);   
  stmesg.mesgid=mesgid++; vcache.push_back(stmesg);   

  pthread_mutex_unlock(&mutex); // 解锁。

  sem_post(&sem);  // 信号加1。
  sem_post(&sem);  // 信号加1。
  sem_post(&sem);  // 信号加1。
  sem_post(&sem);  // 信号加1。
  sem_post(&sem);  // 信号加1。
  sem_post(&sem);  // 信号加1。

}

int main()
{
  signal(15,incache);  // 接收15的信号,调用生产者函数。

  sem_init(&sem,0,0);  // 初始化信号量。
  pthread_mutex_init(&mutex,NULL); // 初始化互斥锁。

  pthread_t thid1,thid2,thid3;
  pthread_create(&thid1,NULL,outcache,NULL);
  pthread_create(&thid2,NULL,outcache,NULL);
  pthread_create(&thid3,NULL,outcache,NULL);

  pthread_join(thid1,NULL);
  pthread_join(thid2,NULL);
  pthread_join(thid3,NULL);

  return 0;

} 

作者:C语言技术网 https://www.bilibili.com/read/cv7523793 出处:bilibili

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值