条件变量函数pthread_cond_timedwait实现业务场景

简介: 条件变量函数pthread_cond_timedwait实现业务场景

工作中在进行通信业务开发时,遇到一种超时时间内收到回复做处理的业务场景,使用锁+条件变量实现

1:互斥锁和自旋锁接口梳理

1:条件变量通常配合互斥锁一起使用:

相关定义:

       pthread_mutex_t g_mutex;

       pthread_cond_t g_cond;

相关初始化:

       1:函数初始化/销毁:

           pthread_mutex_init(&g_mutex, NULL);

           pthread_cond_init(&g_cond, NULL);

           pthread_cond_destroy(&g_cond);

           pthread_mutex_destroy(&g_mutex);

       2:静态初始化: ==》不用关注释放

           pthread_cond_t blank_cond = PTHREAD_COND_INITIALIZER;

           memcpy(&g_cond, &blank_cond, sizeof(pthread_cond_t));

           pthread_mutex_t blank_mutex = PTHREAD_MUTEX_INITIALIZER;

           memcpy(&g_mutex, &blank_mutex, sizeof(pthread_mutex_t));

相关使用:

       1:互斥锁加锁/解锁相关函数

           pthread_mutex_lock(&g_mutex);     //加锁

           pthread_mutex_unlock(&g_mutex); //解锁

       2:条件变量相关函数

           pthread_cond_broadcast(&g_cond);  //唤醒所有加锁线程

           pthread_cond_signal(&g_cond);     //唤醒其中一个加锁线程

           pthread_cond_wait(&g_cond, &g_mutex); //没有唤醒一直等待

           pthread_cond_timedwait(&g_cond, &g_mutex, &outtime);

               //等待唤醒,如果超过定义的时间,则也可以运行

               //如果是超时唤醒,返回值非0

2:自选锁的一些梳理

数据结构:

       pthread_spinlock_t spinlock;

相关接口:

       int pthread_spin_init(pthread_spinlock_t *, int);

       int pthread_spin_destroy(pthread_spinlock_t *);

       

       int pthread_spin_lock(pthread_spinlock_t *);

       int pthread_spin_unlock(pthread_spinlock_t *);

       int pthread_spin_trylock(pthread_spinlock_t *);

初始化时第二个参数指定:

       PTHREAD_PROCESS_SHARED:该自旋锁可以在多个进程中的线程之间共享。

       PTHREAD_PROCESS_PRIVATE: 仅初始化本自旋锁的线程所在的进程内的线程才能够使用该自旋锁。

2:相关测试代码:

//对条件变量锁进行测试 超时等待
/*********************************************
多个线程通信,要实现一种唤醒或者超时唤醒的处理,
pthread_cond_timedwait 进行测试
实现方案:
  申请两个线程,同样的逻辑进行测试
********************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/time.h>
pthread_mutex_t g_mutex;
pthread_cond_t g_cond;
//两个线程同样的回调
void* thread_callback(void* arg);
int main()
{
  //初始化全局锁和条件变量
  pthread_mutex_init(&g_mutex, NULL);
  pthread_cond_init(&g_cond, NULL);
  pthread_t t[2];
  //创建两个线程执行回调
  for(int i=0; i<2; i++)
  {
    int ret = pthread_create(&t[i], NULL, thread_callback, (void*)1);
    if(ret != 0)
    {
      printf("pthread_create failed. %d \n", ret);
      return -1;
    }
  }
  sleep(2);
  //主线程实现对线程回调函数中的阻塞等待进行唤醒
  pthread_mutex_lock(&g_mutex);
  pthread_cond_signal(&g_cond); //唤醒一个
  pthread_mutex_unlock(&g_mutex);
  //相关等待及销毁处理
  for(int i = 0; i<2; i++)
  {
    pthread_join(t[i], NULL);
  }
  pthread_cond_destroy(&g_cond);
  pthread_mutex_destroy(&g_mutex);
  return 0;
}
void* thread_callback(void* arg)
{
  //这里两个线程都用pthread_cond_timedwait 进行等待唤醒
  //两种不同的获取时间的方式
  struct timeval now;
  struct timespec outtime;
  gettimeofday(&now, NULL);
  outtime.tv_sec = now.tv_sec + 5; //s
    outtime.tv_nsec = now.tv_usec * 1000; //微妙转为纳秒
    int ret = -1;
    //锁+条件变量实现线程的阻塞一定时间, 或者被唤醒
    pthread_mutex_lock(&g_mutex);
    //等待一定的时间,进行唤醒
  ret = pthread_cond_timedwait(&g_cond, &g_mutex, &outtime);
  pthread_mutex_unlock(&g_mutex);
  printf("pthread_cond_timedwait return %d \n", ret);
  return NULL;
}

代码运行结果:

可以看出,超时返回值非0

pthread_cond_timedwait return 0 
pthread_cond_timedwait return 110

 

目录
相关文章
|
编解码 Linux 编译器
使用 C++ 方式实现 GBK 到 UTF-8 转码 (win / linux)
使用 C++ 的方式处理在 Windows 平台和 Linux 平台,编码字符集从 GBK 到 UTF-8 转码,C++ 存在多种方式实现
3819 1
|
XML 存储 JSON
JSON、JSONObject 与 JSONArray 详细介绍及其应用方式
JSON、JSONObject 与 JSONArray 详细介绍及其应用方式
4477 3
JSON、JSONObject 与 JSONArray 详细介绍及其应用方式
|
监控 Java Apache
阿里巴巴开源 Sentinel 限流方案搭建
Sentinel是阿里开源的一个限流方案框架具有以下特征: 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
|
云计算
云计算自旋锁问题之使用std::recursive_mutex如何解决
云计算自旋锁问题之使用std::recursive_mutex如何解决
171 2
|
算法 开发者 索引
【C++11算法】random_shuffle和shuffle
【C++11算法】random_shuffle和shuffle
690 0
|
监控 Linux 网络安全
在Linux中,如何进行网络资源的隔离?
在Linux中,如何进行网络资源的隔离?
|
存储 缓存 分布式计算
高并发架构设计三大利器:缓存、限流和降级问题之缓存的应对策略问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之缓存的应对策略问题如何解决
186 2
|
安全 Unix Linux
LD_PRELOAD劫持(超详细篇)
LD_PRELOAD劫持(超详细篇)
1295 0
|
消息中间件 Linux API
Linux进程间通信(IPC) Linux消息队列:讲解POSIX消息队列在Linux系统进程间通信中的应用和实践
Linux进程间通信(IPC) Linux消息队列:讲解POSIX消息队列在Linux系统进程间通信中的应用和实践
725 1
Linux进程间通信(IPC) Linux消息队列:讲解POSIX消息队列在Linux系统进程间通信中的应用和实践
|
Android开发
Android Makefile中inherit-product函数和include的区别
Android Makefile中inherit-product函数和include的区别
311 0

热门文章

最新文章