Linux条件变量的定义是什么,怎么理解
Admin 2022-07-27 群英技术资讯 304 次浏览
互斥量就是一把锁,在访问数据时能保证同一时间内只有一个线程访问数据,在访问完以后再释放互斥量上的锁。
条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待"条件变量的条件成立"而挂起;另一个线程使"条件成立"(给出条件成立信号)。为了防止竞争,条件变量的使用总是和一个互斥锁结合在一起。
条件变量应该和互斥量配合使用,以避免出现条件竞争,一个线程预备等待一个条件变量,当它在真正进入等待之前,另一个线程恰好触发了该条件.
条件变量采用的数据类型是pthread_cond_t,在使用之前必须要进行初始化,与互斥锁类型,也包括两种方式.
静态初始化:可以把常量PTHREAD_COND_INITIALIZER赋给静态分配的条件变量;
动态初始化:在申请内存(malloc)后,通过pthread_cond_init进行初始化.注意在释放内存前需要调用pthread_cond_destory.动态方式调用pthread_cond_init()函数,API定义如下:
int pthread_cond_init(pthread_cond_t *cond, pthread_condattr_t *cond_attr)
结构pthread_condattr_t是条件变量的属性结构,和互斥锁一样我们可以用它来设置条件变量是进程内可用还是进程间可用,默认值是PTHREAD_ PROCESS_PRIVATE,即此条件变量被同一进程内的各个线程使用;如果选择为PTHREAD_PROCESS_SHARED则为多个进程间各线程公用。注意初始化条件变量只有未被使用时才能重新初始化或被释放。
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)
等待条件有两种方式:无条件等待pthread_cond_wait()和计时等待pthread_cond_timedwait(),其中计时等待方式如果在给定时刻前条件没有满足,则返回ETIMEOUT,结束等待,其中abstime以与time()系统调用相同意义的绝对时间形式出现,0表示格林尼治时间1970年1月1日0时0分0秒。
无论哪种等待方式,都必须和一个互斥锁配合,以防止多个线程同时请求pthread_cond_wait()(或pthread_cond_timedwait(),下同)的竞争条件(Race Condition)。mutex互斥锁必须是普通锁(PTHREAD_MUTEX_TIMED_NP)或者适应锁(PTHREAD_MUTEX_ADAPTIVE_NP),且在调用pthread_cond_wait()前必须由本线程加锁(pthread_mutex_lock()),而在更新条件等待队列以前,mutex保持锁定状态,并在线程挂起进入等待前解锁。在条件满足从而离开pthread_cond_wait()之前,mutex将被重新加锁,以与进入pthread_cond_wait()前的加锁动作对应。
激发条件有两种形式,pthread_cond_signal()激活一个等待该条件的线程,存在多个等待线程时按入队顺序激活其中一个;而pthread_cond_broadcast()则激活所有等待线程。
#include <pthread.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; struct node { int n_number; struct node *n_next; } *head = NULL; /*[thread_func]*/ static void cleanup_handler(void *arg) { printf("Cleanup handler of second thread.\n"); free(arg); (void)pthread_mutex_unlock(&mtx); } static void *thread_func(void *arg) { struct node *p = NULL; pthread_cleanup_push(cleanup_handler, p); while (1) { pthread_mutex_lock(&mtx); while (head == NULL) { pthread_cond_wait(&cond, &mtx); } p = head; head = head->n_next; printf("Got %d from front of queue\n", p->n_number); free(p); pthread_mutex_unlock(&mtx); } pthread_cleanup_pop(0); return 0; } int main(void) { pthread_t tid; int i; struct node *p; pthread_create(&tid, NULL, thread_func, NULL); /*[tx6-main]*/ for (i = 0; i < 5; i++) { p = malloc(sizeof(struct node)); p->n_number = i; pthread_mutex_lock(&mtx); p->n_next = head; head = p; pthread_cond_signal(&cond); pthread_mutex_unlock(&mtx); sleep(1); } printf("thread 1 wanna end the line.So cancel thread 2.\n"); pthread_cancel(tid); pthread_join(tid, NULL); printf("All done -- exiting\n"); return 0; }
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
CentOS7安装和配置FTP
如果我们要查看linux服务器的内存使用情况,可以利用free命令或者使top命令。
查看方法:1、用“df -h”命令;2、用“lsblk”命令;3、用“sudo lshw -class disk”命令;4、用“fdisk -l”命令;5、用“cat /proc/partitions”命令;6、用“lsscsi”命令。
linux系统怎么判断路由转发功能是否开启?linux系统可以直接查看路由器转发功能是否打开了,显示数字1是打开路由器转发,显示数字0,路由器转发功能未曾打开,下面我们就来看看详细的步骤
linux下移动文件到指定目录的方法:可以利用mv命令来进行移动,如【mv * ../】,表示移动当前文件夹下的所有文件到上一级目录中。mv命令用于为文件或目录改名或者移动文件。
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008