信号灯文件锁linux线程,linux——线程同步(互斥量、条件变量、信号灯、文件锁)...

一、说明

linux的线程同步涉及:

1、互斥量

2、条件变量

3、信号灯

4、文件读写锁

信号灯很多时候被称为信号量,但个人仍觉得叫做信号灯比较好,因为可以与“SYSTEM V IPC的信号量”相区分(如有不同意见,欢迎探讨)。

二、互斥量

1、定义

互斥锁允许我们锁住某个对象(某个变量、某段代码等),使得每次只能有一个线程访问他。我们在对需要保护的对象进行操作前,先把互斥锁上锁,如果上锁成功,就不会有别的线程再来操作被保护的对象。如果上锁不成功,线程就会阻塞(可能是有别的线程已经把互斥锁锁住了),直到互斥锁被打开。从而保护了要保护的对象。

2、相关函数

a.pthread_mutex_init

函数原型:

#include

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr);

功能:初始化互斥锁

参数:mutex为pthread_mutex_t类型的变量的地址,也就是互斥锁的名字;

mutexattr为pthread_mutexattr_t类型的变量地址,用于设置锁的属性,默认可以设为NULL;

返回:成功0,错误返回错误代码。

备注:初始化互斥锁还有个简便的方法,比如对 pthread_mutex_t a; 进行初始化,则直接写成:pthread_mutex_t a = PTHREAD_MUTEX_INITIALIZER; 即可。

b.pthread_mutex_destroy

函数原型:

int pthread_mutex_destroy(pthread_mutex_t *mutex);

功能:销毁互斥锁

参数:mutex为要销毁的互斥锁的地址

返回:成功0,错误返回错误代码。

c.pthread_mutex_lock

函数原型:

int pthread_mutex_lock(pthread_mutex_t *mutex));

功能:上锁

参数:同上

返回:同上

d.pthread_mutex_unlock

函数原型:

int pthread_mutex_unlock(pthread_mutex_t *mutex);

功能:解锁

参数:同上

返回:同上

3、例程

#include

#include

pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;

int cnt=0;

void *func1(void *b)

{

int a=2000;

usleep(rand()%2000);

while(a--)

{

printf("11111=%d.\n",a);

printf("\tpthread 1 start to lock.\n");

pthread_mutex_lock (&mylock);

printf("\tpthread 1 locked.\n");

cnt++;

printf("\t++cnt=%d\n",cnt);

printf("\tpthread 1 start to unlock.\n");

pthread_mutex_unlock (&mylock);

printf("\tpthread 1 unlocked.\n");

}

}

void *func2(void *b)

{

int a=2000;

usleep(rand()%2000);

while(a--)

{

printf("22222=%d.\n",a);

printf("\tpthread 2 start to lock.\n");

pthread_mutex_lock (&mylock);

printf("\tpthread 2 locked.\n");

if(cnt>0)

{

cnt--;

printf("\t--cnt=%d\n",cnt);

}

printf("\tpthread 2 start to unlock.\n");

pthread_mutex_unlock (&mylock);

printf("\tpthread 2 unlocked.\n");

if(!cnt)

{

usleep(1);

}

}

}

int main(void)

{

pthread_t a,b;

pthread_create(&a, NULL, func1, (void*)0 );

pthread_create(&b, NULL, func2, (void*)0 );

pthread_join (a, NULL);

pthread_join (b, NULL);

return 0;

}程序中,cnt即为要保护的对象,两个线程,同一时刻只能有一个线程在访问这个对象。

三、条件变量

1、定义

条件变量与互斥量一起使用时,允许线程以无竞争的方式等待特定条件的发生。条件本身受互斥量的保护,线程在改变条件状态前,必须先锁住互斥量,其他线程在获得互斥量之前不会觉察到这种变化(因为互斥量被正在改变条件的线程锁着,其他线程没有获得互斥量就没有机会觉察到变化)

2、相关函数

a.pthread_cond_init

函数原型:

int pthread_cond_init (pthread_cond_t * cond, const pthread_condattr_t *cond_attr);

功能:初始化条件变量

参数:cond条件变量名的地址

cond_attr为条件变量的属性

返回:成功0,错误返回错误编号

备注:简便的初始化方法:pthread_cond_t a = PTHREAD_COND_INITIALIZER;

b.pthread_cond_destroy

函数原型:

int pthread_cond_destroy (pthread_cond_t *cond);

功能:销毁条件变量

参数:cond条件变量名的地址

返回:成功0,错误返回错误代码

c.pthread_cond_wait

函数原型:

int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex);

功能:等待互斥锁mutex下的条件cond的发生

参数:cond为要等待的条件变量

mutex为保护条件变量的互斥锁

返回:成功0,错误返回错误代码

d.pthread_cond_signal

函数原型:

int pthread_cond_signal (pthread_cond_t *cond);

功能:发送条件变量cond

参数:cond为要发送的条件变量

返回:成功0,否则返回错误编号 备注:

只通知某一个等待该条件的线程

e.pthread_cond_broadcast

功能:发送条件变量cond

参数:cond为要发送的条件变量

返回:成功0,否则返回错误编号

备注:通知所有等待该条件的线程

3、例程(与某嵌入式面试题类似:三个线程各自打印A、B、C,要求按顺序ACBCACBC输出)

#include

#include

#include

int sequence=1;

int eat = 1;

pthread_mutex_t productor_mutex = PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t my_cond = PTHREAD_COND_INITIALIZER;

pthread_mutex_t productor_mutex1 = PTHREAD_MUTEX_INITIALIZER;

pthread_cond_t my_cond1 = PTHREAD_COND_INITIALIZER;

void *productor1()

{

int my_sequence = 1;

while(1)

{

pthread_mutex_lock(&productor_mutex);

while(sequence!=my_sequence)

{

pthread_cond_wait (&my_cond, &productor_mutex);

}

pthread_mutex_lock(&productor_mutex1);

while(eat!=1)

{

pthread_cond_wait (&my_cond1, &productor_mutex1);

}

printf("A ");

eat=0;

pthread_cond_broadcast (&my_cond1);

pthread_mutex_unlock (&productor_mutex1);

sequence=2;

pthread_cond_broadcast(&my_cond);

pthread_mutex_unlock (&productor_mutex);

}

return 0;

}

void *productor2()

{

int my_sequence=2;

while(1)

{

pthread_mutex_lock(&productor_mutex);

while(sequence!=my_sequence)

{

pthread_cond_wait (&my_cond, &productor_mutex);

}

pthread_mutex_lock(&productor_mutex1);

while(eat!=1)

{

pthread_cond_wait (&my_cond1, &productor_mutex1);

}

printf("B ");

eat=0;

pthread_cond_broadcast (&my_cond1);

pthread_mutex_unlock (&productor_mutex1);

sequence=1;

pthread_cond_broadcast (&my_cond);

pthread_mutex_unlock (&productor_mutex);

}

return 0;

}

void *consumer()

{

long a=200;

while(a--)

{

pthread_mutex_lock(&productor_mutex1);

while(eat!=0)

{

pthread_cond_wait (&my_cond1, &productor_mutex1);

}

printf("C ");

eat=1;

pthread_cond_broadcast (&my_cond1);

pthread_mutex_unlock (&productor_mutex1);

}

return 0;

}

int main(void)

{

pthread_t pth1=0,pth2=0,pth3=0;

int err=-1;

void *tret=NULL;

err = pthread_create(&pth1,NULL,productor1,NULL);

if(err)

{

printf("creat pthread productor failed!\n");

exit(1);

}

err = pthread_create(&pth2,NULL,productor2,NULL);

if(err)

{

printf("creat pthread productor failed!\n");

exit(1);

}

err = pthread_create(&pth3,NULL,consumer,NULL);

if(err)

{

printf("creat pthread consumer failed!\n");

exit(1);

}

err = pthread_join(pth3,&tret);

if(err)

printf("can't join pthread consumer!\n");

else

printf("pthread consumer exit with %d!\n",(int)tret);

pthread_cancel(pth1);

pthread_cancel(pth2);

exit(0);

}

四、信号灯

1、定义

又叫做计数信号量,post一次信号量的值+1;wait一次,信号量的值-1,如果信号量的值已经为0,则wait将阻塞直至信号量的值>0;

2、相关函数

a.sem_init

函数原型:

#include

int sem_init(sem_t *sem, int pshared, unsigned int value);

功能:初始化信号量

参数:sem为要初始化的信号量地址

value为初始化设置的值

返回:X?

b.sem_destroy

函数原型:

int sem_destroy(sem_t * sem);

功能:销毁信号量

参数:sem要销毁的信号量地址

返回:X?

c.sem_post

函数原型:

int sem_post(sem_t * sem);

功能:信号量值+1

参数:

返回:

d.sem_wait

函数原型:

int sem_wait(sem_t * sem);

功能:信号量值-1

参数:sem要销毁的信号量地址

返回:X?

e.sem_getvalue

函数原型:

int sem_getvalue(sem_t * sem);

功能:获取信号量当前值

参数:

返回:X?

3、例程

五、文件读写锁

1、定义

2、相关函数

3、例程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/244599.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

wpf 大数据界面_24小时删!WPF 界面开发可视化数据源500行代码分享

通过DevExpress WPF Controls,您能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。在本教程中,您将完成可视化数据源所需的步骤。应该执行以下步骤,本文我们将为大…

反向题在测试问卷信效度_(完整版)问卷信度效度检验

从统计数据质量角度谈调查问卷的设计质量一、引言从保证统计数据质量的统计工作过程看,统计数据质量可以被划分为统计设计质量、统计调查质量、统计整理质量、统计分析质量以及数据发布传输质量等。统计设计质量是保证统计数据质量的首要环节,在统计数据…

朋友圈加粗字体数字_数字+符码:医院数码导视系统畅想起来

(建筑平面设计图边缘有横竖轴线编码)医院导视系统要做到最简单、最清晰的表达,和谐地融入室内环境并具有一定的弹性,能够适应变化,并适应未来科技的发展,接纳信息化,与管理、服务互联互通。文 | 谷 建 中衡设计集团股…

linux用光盘作yum源实验步骤,Linux使用系统光盘作为YUM源

CentOS 使用方法挂载光盘Linux代码# mkdir /media/cdrom# mount /dev/cdrom /media/cdromyum源文件说明在 /etc/yum.repos.d/ 目录中有CentOS-Base.repo和CentOS-Media.repo两个文件CentOS-Base.repo 记录的是网络上的资源信息CentOS-Media.repo 记录的光盘上的资源信息&#x…

苹果x出现绿线怎么修复_苹果x听筒声音小,苹果x通话声音小怎么办

苹果x听筒声音小,苹果x通话声音小怎么办?相信使用苹果x手机的人大多都会遇见这类情况吧。iPhone手机出现听筒声音小的现象,首先我们要确定出现听筒声音小的故障原因是什么,如果是软件方面的原因造成的,就可以自己调试解决&#x…

wxpython输入框_基于wxPython的GUI实现输入对话框(1)

本文实例为大家分享了基于wxpython的gui实现输入对话框的具体代码,供大家参考,具体内容如下编程时,免不了要输入一些参数等,这时输入对话框就派上用处了:#-*- coding:utf-8 -*-#~ #-------------------------------------------------------------------…

linux grep -11,11个高级Linux字符类和括号表达式的grep命令

你是否曾经在你需要的一种局面搜索字符串,文字或图案的文件里面呢? 如果是,那么grep工具来在这样的情况下派上用场。grep的是为其匹配一个正则表达式搜索行纯文本数据的命令行实用程序。 如果您将分词的grep如 g/re/p,然后grep的含…

tortoisegitpull 并合_tortoiseGIT 本地分支创建合并

接下来是使用tortoiseGIT二、图解使用tortoiseGIT这里只是做一些最基本的功能的演示:创建版本库,提交(commit)文件,推送(push)文件,更新文件,创建分支。简介:git属于分布式版本控制器,其实每个人…

视频图像处理平台对比_对比传统智能结算,戈子视觉结算有了质的改变

相比于使用的RFID原理技术的传统智能结算台,戈子视觉结算台使用的是由戈子科技自主研发的视觉结算系统,其采用的是图像处理技术,通过对餐具扫描识别进行结算。相比于传统智能结算台,其在功能上有很大的提升与创新。戈子视觉结算系…

C语言中字符型和浮点型能否相加,C语言中数据结构的基本类型(整型、浮点型和字符型)...

#include int main(){/**********************************************************// 我们列出的是VS2008的内存占用情况// 一、整型变量的分类:// 1,基本整型,以int表示// 2,短整型,以short int表示,或以…

vs code linux opencv,ubuntu+vscode 测试运行opencv

ubuntuvscode 测试运行opencvubuntuvscode 测试运行opencv之前再ubuntu配置好了opencv,今天测试运行一下。1.创建一个文件夹opencvtest2.在文件夹内打开终端,创建一个cpp文件,再放一张图片。touch mian.cpp3.vim或者文本管理器打开 复制好程序vim命令&am…

wp自定义帖子没标签_拼多多搜索智能推广和自定义推广区别在哪里?

大家好我是牧童,商家在开多多搜索的时候,会发现推广方案中有个智能推广以及自定义推广,很多商家不知道该如何选择,然后就两个计划都建了。之后会发现有的时候智能推广的数据要比自定义推广好,但有的时候智能推广的数据…

python sort 部分元素_Python 简单排序算法-选择、冒泡、插入排序实现

写文章主要是记录自己每天学习的东西,本篇文章主要介绍数据结构中常用的简单的排序算法,虽然这些算法用Python实现起来不是十分的高效,不如c、java之类的运行速度快,应用Python实现主要是为了:1、证明我已经理解了这些…

numpy安装_Python进阶之NumPy快速入门(一)

前言NumPy是Python的一个扩展库,负责数组和矩阵运行。相较于传统Python,NumPy运行效率高,速度快,是利用Python处理数据必不可少的工具。这个NumPy快速入门系列分为四篇,包含了NumPy大部分基础知识,每篇阅读…

gc java root_聊聊Java的GC机制

原标题:聊聊Java的GC机制近日,MIUI在小米全球社区发布公告,表示MIUI将在全球市场销售的手机中预装谷歌拨号及谷歌消息应用程序(中国、印度、印度尼西亚等市场除外)。小米表示,小米9T Pro之后的设备在全球范围内都将会预装上述两款…

c语言课程设计 第2版,c语言课程设计报告模版(电子版)2.pdf

c语言课程设计报告模版(电子版)2大连交通大学 软件学院 C语言课程设计报告SOFTWARE INSTITUTEOF DALIAN JIAOTONG UNIVERSITY EXPERIMENT DESIGNINGC语言课程设计报告Course Design reporter课程名称 : C语言课程设计英文名称 : Course Design of C Programming专 业…

jmeter跨线程组传多个值_Jmeter 跨线程组传递参数 之两种方法(转)

终于搞定了Jmeter跨线程组之间传递参数,这样就不用每次发送请求B之前,都需要同时发送一下登录接口(因为同一个线程组下的请求是同时发送的),只需要发送一次登录请求,请求B直接用登录请求的参数即可,直到登录接口的参数…

wallpaper代码_70 行 python 代码实现壁纸批量下载!

好久没有写文章了,因为最近都在适应新的岗位,以及利用闲暇时间学习python。这篇文章是最近的一个python学习阶段性总结,开发了一个爬虫批量下载某壁纸网站的高清壁纸。注意:本文所属项目仅用于python学习,严禁作为其他…

c语言调用go函数,C中调用go中的回调函数

在用go包装某些c库时(如glut),需要将go函数当作回调函数传递给c库(如glutDisplayFunc(&draw)中的draw函数,我想将go写的函数传过去),应该怎么做?我写了一个示例,但一直不成功,不知道为什么?…

100g流量在电脑上可以用多久_三大运营商5G体验方案出炉!100G一个月够不够?...

前段时间,工信部向中国移动、中国联通、中国电信、中国广电发放5G商用牌照,这也意味着,我国5G网络正式开始被商用。并且目前三大运营商都已完成了5G网络下的终端组网测试,计划于今年第三季度开始进行试商用。而就在近期&#xff0…