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

 

目录
相关文章
|
5月前
|
存储 缓存 安全
C语言进程(第二章,wait,sleep,waitpid,pthread_mutex_lock,pthread_mutex_unlock)
C语言进程(第二章,wait,sleep,waitpid,pthread_mutex_lock,pthread_mutex_unlock)
115 0
pthread_mutex_unlock()出错
pthread_mutex_unlock()出错
148 0
使用超时加锁:pthread_mutex_timedlock
使用超时加锁:pthread_mutex_timedlock
237 0
Pthread线程使用详解
文中先讲解函数,再运行实例,以及一些注意事项
226 0
|
Linux API
pthread_mutex_init & 互斥锁pthread_mutex_t的使用
pthread_mutex_init l         头文件: #include l         函数原型: int pthread_mutex_init(pthread_mutex_t *restrict mutex,const pthread_mutexattr_t *restrict attr); pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; l         函数作用: 该函数用于C函数的多线程编程中,互斥锁的初始化。
1914 0
|
C++
【C++ 语言】pthread_mutex_t 互斥锁
【C++ 语言】pthread_mutex_t 互斥锁
281 0