linux 线程同步(二)
信号量
信号量是相互排斥锁的升级版把相互排斥锁中1变成了n。举个简单的样例:如果如今有10个人,有一部手机。这10个人都竞争来使用手机打电话这就是相互排斥锁。对于信号量,如今可能是有4部手机,这10个人都竞争来使用手机打电话。相比相互排斥锁信号量由1变成了4。信号量相也就是操作系统中pv操作,它广泛应用进程或者线程间的同步与相互排斥。
相关库函数介绍
#include <semaphore.h>//所需头文件
//初始化信号量sem初始化的时候能够指定信号量的初始值,以及能否够在多进程间共享value表示要信号量初始值,pshared表示是否再多进程之前共享。 0表示不在多进程间
共享,非0表示在多进程之间共享详细能够man sem_init
//成功返回0,出错返回-1
int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_wait(sem_t *sem)//相当于p操作
int sem_try_wait(sem_t *sem)//相当于p操作。在信号量值大于0时都能将信号量的值减一,与上面sem_wait的差别是,在信号值小于0时
int sem_post(sem_t *sem)//相当于v操作
int sem_getvalue(sem_t *sem)//用于得到信号量的值
int sem_destory(sem_t *sem) //释放信号量
信号量实例:生产者消费值
#include<stdio.h>
#include<stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#define BUFSIZE 10
int buf[BUFSIZE];
sem_t consumer_sem,producer_sem;
void *consumer(void *arg)
{
int c=0;
while(1)
{
sem_wait(&consumer_sem);//開始消费consumer_sem值减一
printf("consumer %d: %d\n",c,buf[c]);//消费数据
c++;
c=c%BUFSIZE;
sleep(1);//睡眠1s
sem_post(&producer_sem);//producer_sem值加1
}
}
void *producer(void *arg)
{
int p=0;
while(1)
{
sem_wait(&producer_sem);//開始生产producer_sem值减一
buf[p]=rand() % 1000 + 1;//生产数据
printf("producer %d: %d\n",p,buf[p]);
p++;
p=p%BUFSIZE;
sem_post(&consumer_sem);//consumer_sem值加1 }
} int main()
{ sem_init(&consumer_sem,0,0);
sem_init(&producer_sem,0,BUFSIZE); pthread_t pid,cid;
pthread_create(&pid,NULL,producer,NULL);
pthread_create(&cid,NULL,consumer,NULL); pthread_join(pid, NULL);
pthread_join(cid, NULL);
sem_destroy(&consumer_sem);
sem_destroy(&producer_sem);
return 0; }
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
条件变量
条件变量是利用线程间共享的全局变量进行同步的一种机制,主要包含两个动作:一个线程等待"条件变量的条件成立"而挂起;还有一个线程使"条件成立"(给出条件成立信号)。
为了防止竞争,条件变量的使用总是和一个相互排斥锁结合在一起。
条件变量类型为 pthread_cond_t。
相关库函数简单介绍
#include<pthread.h>
int pthread_cond_destroy(pthread_cond_t *cond);//条件变量的资源释放
int pthread_cond_init(pthread_cond_t *cond,const pthread_condattr_t *attr);//条件变量的初始化
#include<pthread.h>
int pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t *mutex,
const struct timespec *abstime);
int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex);
//等待某个条件是否成立。对于timewait()函数除了等待以外。能够设置一个时长。
int pthread_cond_signal(pthread_cond_t *cond);//种情况是仅仅有一个线程收到后运行动作。 //活动线程仅仅须要唤醒第一个正在睡眠的线程。如果您仅仅对队列加入了一个工作作业。 那么仅仅须要唤醒一个工作程序线程(再唤醒其他线程是不礼貌的! )
int pthread_cond_broadcast(pthread_cond_t *cond);//通过广播的形式发给子线程消息。子线程竞争运行。
不管哪种等待方式,都必须和相互排斥锁结合,以防止多个线程同一时候请求pthread_cond_wait()(或pthread_cond_timedwait())的竞争条件,且在调用pthread_cond_wait()前必须由本线程加锁(pthread_mutex_lock()),而在更新条件等待队列曾经,mutex保持锁定状态。并在线程挂起进入等待前解锁。在条件满足从而离开pthread_cond_wait()之前,mutex将被又一次加锁,以与进入pthread_cond_wait()前的加锁动作相应。
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h> struct msg {
struct msg *next;
int num;
}; struct msg *head;
/* 条件变量 */
pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
void *consumer(void *p)
{
struct msg *mp;
while(1)
{
pthread_mutex_lock(&lock);
/* pthread_cond_wait(&has_product, &lock);
* 1.堵塞等待has_product被唤醒。
* 2.释放相互排斥锁。 pthread_mutex_unlock(&lock)
* 3.当被唤醒时。解除堵塞,而且又一次去申请获得相互排斥锁 pthread_mutex_lock(&lock)
*/
while (head == NULL)
pthread_cond_wait(&has_product, &lock);//等待 mp = head;
head = mp->next;
pthread_mutex_unlock(&lock);
printf("Consume %d\n", mp->num);
free(mp);
sleep(rand() % 5);
}
} void *producer(void *p)
{
struct msg *mp;
while(1)
{
mp =(struct msg *)malloc(sizeof(struct msg));
mp->num = rand() % 1000 + 1;
printf("Produce %d\n", mp->num);
pthread_mutex_lock(&lock);
mp->next = head;
head = mp;
pthread_mutex_unlock(&lock);
/* pthread_cond_broadcast(&has_product) 唤醒等待队列上的全部线程*/
//发送信号,告诉消费者有产品了
pthread_cond_signal(&has_product);
sleep(rand() % 5);
}
} int main(int argc, char *argv[])
{
pthread_t pid, cid;
srand(time(NULL));
pthread_create(&pid, NULL, producer, NULL);
pthread_create(&cid, NULL, consumer, NULL);
pthread_join(pid, NULL);
pthread_join(cid, NULL);
return 0;
}
linux 线程同步(二)的更多相关文章
- 【转】 Linux 线程同步的三种方法
线程的最大特点是资源的共享性,但资源共享中的同步问题是多线程编程的难点.linux下提供了多种方式来处理线程同步,最常用的是互斥锁.条件变量和信号量. 一.互斥锁(mutex) 通过锁机制实现线程间的 ...
- linux线程同步(1)-互斥量
一.概述 互斥量是线程同步的一种机制,用来保护多线程的共享资源.同一时刻,只允许一个线程对临界区进行 ...
- Linux线程同步之读写锁(rwlock)
读写锁和互斥量(互斥锁)很类似,是另一种线程同步机制,但不属于POSIX标准,可以用来同步同一进程中的各个线程.当然如果一个读写锁存放在多个进程共享的某个内存区中,那么还可以用来进行进程间的同步, 和 ...
- linux线程(二)内存释放
linux线程有两种模式joinable和unjoinable. joinable线程:系统会保存线程资源(栈.ID.退出状态等)直到线程退出并且被其他线程join. unjoinable线程:系统会 ...
- Linux线程同步
1. 线程同步: 当多个控制线程共享相同的内存时,需要确保每个线程看到一致的数据视图.当某个线程可以修改变量,而其他线程也可以读取或者修改这个变量的时候,就需要对这些线程进行同步,以确保他们在访问变量 ...
- Linux 线程同步的三种方法(互斥锁、条件变量、信号量)
互斥锁 #include <cstdio> #include <cstdlib> #include <unistd.h> #include <pthread. ...
- Linux线程同步:条件变量
条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足,它常和互斥锁一起使用.使用时,条件变量被用来阻塞一个线程,当条件不满足时,线程往往解开相应的互斥锁并等待条件发生变化.一旦其它 ...
- linux线程同步(5)-屏障
一.概述 barrier(屏障)与互斥量,读写锁,自旋锁不同,它不是用来保护临界区的.相反,它跟条 ...
- linux线程同步(3)-读写锁
一.概述 读写锁与互斥量的功能类似,对临界区的共享资源进行保护!互斥量一次只让一个线程进入临界区, ...
随机推荐
- [转]解决右键用notepad++打开提示【ShellExecute failed (2): Is this command Correct? (Fix) 】
最近发现右键使用notepad++打开文件时提示如下错误: ShellExecute failed (2): Is this command Correct? ... 经用搜索引擎搜索得知,应该是开启 ...
- CAD参数绘制文字(网页版)
在CAD设计时,需要绘制文字,用户可以设置设置绘制文字的高度等属性. 主要用到函数说明: _DMxDrawX::DrawText 绘制一个单行文字.详细说明如下: 参数 说明 DOUBLE dPosX ...
- 网页显示403. That’s an error的解决方法。
使用Go*gent打开网页,经常出现403. That’s an error.下面是解决的方法. 方法/步骤 一.打开Go*gent的文件目录.不知道找文件目录的,可以在桌面上右键点击Go*g ...
- mybatis generator 覆盖xml文件
mybatis generator默认采用追加方式生成,所以我们如果要重新生成代码的时候那么要先删除原来的文件. 解决办法: 1:创建一个自定义补丁类. OverwriteXmlPlugin.java ...
- Luogu P1315 观光公交
# 解题思路 一开始自己想了一个贪心,虽然贪心的主要思路是对的,但并不会统计游客用的旅行时间.所以就去题解里面看看,第一篇是最小费用最大流,会比较麻烦,所以就去看了看底下的贪心,第一篇贪心被卡掉了,看 ...
- git命令初级
git是开源的分布式版本控制系统,分布式主要区别于集中式代表CVS(Concurrent Version System,遵从C/S架构,同步比较笨拙.)和SVN(Subversion),linux开发 ...
- HYSBZ - 3750 Pieczęć(模拟)
题目: 一张n*m的方格纸,有些格子需要印成黑色,剩下的格子需要保留白色. 你有一个a*b的印章,有些格子是凸起(会沾上墨水)的.你需要判断能否用这个印章印出纸上的图案.印的过程中需要满足以下要求: ...
- poj3134 Power Calculus
题目描述: 你现在有x^1,每动一步可以用当前存在的x^a和x^b获得x^(a+b)或x^(abs(a-b)).给出n(n<=1000),求最少多少步能得到x^n. 题解: IDDFS.枚举步数 ...
- 使用requests+BeaBeautiful Soup爬取妹子图图片
1. Requests:让 HTTP 服务人类 Requests 继承了urllib2的所有特性.Requests支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动确定 ...
- I - DFS(依然是漫水填充)
Description There is a rectangular room, covered with square tiles. Each tile is colored either red ...