互斥锁
锁标志位:
文件: switch_apr.h
/** Lock Flags */#define SWITCH_MUTEX_DEFAULT 0x0 /**< platform-optimal lock behavior */#define SWITCH_MUTEX_NESTED 0x1 /**< enable nested (recursive) locks */#define SWITCH_MUTEX_UNNESTED 0x2 /**< disable nested locks */
初始化锁(递归锁)
static struct {switch_hash_t *files;switch_hash_t *lists;switch_mutex_t *files_mutex;switch_mutex_t *lists_mutex;switch_memory_pool_t *pool;} globals;switch_mutex_init(&globals.lists_mutex, SWITCH_MUTEX_NESTED, globals.pool);
使用锁
switch_mutex_lock(globals.lists_mutex);bl = switch_core_hash_find(globals.lists, argv[1]);switch_mutex_unlock(globals.lists_mutex);
释放锁
switch_mutex_destroy(globals.mutex);
递归锁和非递归锁区别
Mutex可以分为递归锁(recursive mutex)和非递归锁(non-recursive mutex)。可递归锁也可称为可重入锁(reentrant mutex),非递归锁又叫不可重入锁__(non-reentrant mutex)。 二者唯一的区别是,同一个线程可以多次获取同一个递归锁,不会产生死锁。而如果一个线程多次获取同一个非递归锁,则会产生死锁。 引用自: https://blog.csdn.net/zouxinfox/article/details/5838861
读写锁
此处有一个实际的使用场景:
- mod_commands.c里面的bgapi会启动线程执行任务
- 在模块shutdown的时候, 需要判断是否有线程还在运行, 有的话就等待
- bgapi启动的各个线程需要能并发运行
创建读写锁
//静态变量, 只在本文件内有效static switch_thread_rwlock_t *bgapi_rwlock = NULL;//初始化时, 创建读写锁switch_thread_rwlock_create(&bgapi_rwlock, pool);
异步线程读取锁
rdlock为读锁, 所以多个线程并发访问的时候, 不会 因为锁而等待.
static void *SWITCH_THREAD_FUNC bgapi_exec(switch_thread_t *thread, void *obj){...switch_thread_rwlock_rdlock(bgapi_rwlock);...//执行api命令, 以事件返回命令执行结果...switch_thread_rwlock_unlock(bgapi_rwlock);return NULL;}
关闭时释放锁
switch_thread_rwlock_trywrlock尝试写锁, 如果上面的线程还在读锁里面, 则获取写锁失败, 会继续等待.
直到所有的读锁执行完毕退出, 此处才能获取写锁成功.
也就达到等待所有线程执行完毕的目的了.
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_commands_shutdown){int x;for (x = 30; x > 0; x--) {if (switch_thread_rwlock_trywrlock(bgapi_rwlock) == SWITCH_STATUS_SUCCESS) {switch_thread_rwlock_unlock(bgapi_rwlock);break;}if (x == 30) {switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Waiting for bgapi threads.\n");}switch_yield(1000000);}if (!x) {switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Giving up waiting for bgapi threads.\n");}return SWITCH_STATUS_SUCCESS;}
wrlock和trywrlock区别?
trywrlock和wrlock功能基本一致, 唯一的区别是如果获取不到锁, 则trywrlock直接返回失败, 而不是像wrlock进入等待状态.
trywrlock返回失败条件: 另一个线程正在read或者write.
