条件变量函数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

 

目录
相关文章
|
编译器 Shell Android开发
工具技能学习(一):前置技能-makfile、make、.mk
工具技能学习(一):前置技能-makfile、make、.mk
828 0
|
Ubuntu Linux 编译器
openssl 的编译(linux、Ubuntu) 和 交叉编译(arm、Hi3531A)的问题分析、解决
openssl 的编译(linux、Ubuntu) 和 交叉编译(arm、Hi3531A)的问题分析、解决
3090 0
|
监控 Java Apache
阿里巴巴开源 Sentinel 限流方案搭建
Sentinel是阿里开源的一个限流方案框架具有以下特征: 丰富的应用场景:Sentinel 承接了阿里巴巴近 10 年的双十一大促流量的核心场景,例如秒杀(即突发流量控制在系统容量可以承受的范围)、消息削峰填谷、集群流量控制、实时熔断下游不可用应用等。
|
Java Linux
【linux线程(三)】生产者消费者模型详解(多版本)
【linux线程(三)】生产者消费者模型详解(多版本)
|
消息中间件 Linux API
Linux进程间通信(IPC) Linux消息队列:讲解POSIX消息队列在Linux系统进程间通信中的应用和实践
Linux进程间通信(IPC) Linux消息队列:讲解POSIX消息队列在Linux系统进程间通信中的应用和实践
1089 1
Linux进程间通信(IPC) Linux消息队列:讲解POSIX消息队列在Linux系统进程间通信中的应用和实践
|
存储 NoSQL Linux
linux之core文件如何查看和调试
通过设置和生成 core 文件,可以在程序崩溃时获取详细的调试信息。结合 GDB 等调试工具,可以深入分析 core 文件,找到程序崩溃的具体原因,并进行相应的修复。掌握这些调试技巧,对于提高程序的稳定性和可靠性具有重要意义。
7363 6
|
Unix Linux 数据处理
Linux命令stty详解
`stty`是Linux命令,用于设置和查看终端参数,如波特率、字符处理和控制字符。它直接与终端驱动交互,支持多种选项以适应不同的配置需求。例如,`stty -a`显示当前设置,`stty -echo`关闭回显,`stty 115200 cs8`调整波特率和字符大小。注意修改设置可能影响终端行为,建议先备份(`stty -g`)并谨慎操作。查阅手册页以获取详细信息。
|
Linux 调度 C语言
【Linux C/C++ 线程同步 】Linux互斥锁和条件变量:互斥锁和条件变量在Linux线程同步中的编程实践
【Linux C/C++ 线程同步 】Linux互斥锁和条件变量:互斥锁和条件变量在Linux线程同步中的编程实践
596 0

热门文章

最新文章