当前位置: 首页 > news >正文

广告策划书目录虞城seo代理地址

广告策划书目录,虞城seo代理地址,网页和网站的联系,招聘网站模板页〇、前言 本文是对《OSTEP》第三十章的实践与总结。 一、条件变量 #include <pthread.h> #include <stdio.h> #include <assert.h>int buffer; int count 0; // 资源为空// 生产,在 buffer 中放入一个值 void put(int value) {assert(count 0);count 1…

〇、前言

本文是对《OSTEP》第三十章的实践与总结。

一、条件变量

#include <pthread.h>
#include <stdio.h>
#include <assert.h>int buffer;
int count = 0; // 资源为空// 生产,在 buffer 中放入一个值
void put(int value) {assert(count == 0);count = 1;buffer = value;
}
// 消费,取出 buffer 中的值
int get() {assert(count == 1);count = 0;return buffer;
}/***********第一版本**********/
// 生产者
void *producer(void *arg) {int loops = *((int *)arg);for (int i = 0; i < loops; i++) {put(i);}return NULL;
}
// 消费者
void *consumer(void *arg) {while (1) {int temp = get();printf("消费的值:%d\n", temp);}return NULL;
}int main() {pthread_t p1, p2;int arg = 100;pthread_create(&p1, NULL, producer, &arg);pthread_create(&p2, NULL, consumer, NULL);// 等待两个线程结束pthread_join(p1, NULL);pthread_join(p2, NULL);return 0;
}

运行:

*** chap30_条件变量 % gcc -o a con_prodece.c
*** chap30_条件变量 % ./a
Assertion failed: (count == 0), function put, file con_prodece.c, line 10.
消费的值:0
Assertion failed: (count == 1), function get, file con_prodece.c, line 16.
zsh: abort      ./a

可以看到,断言直接失败。

pthread_cond_t cond;
pthread_mutex_t mutex;
/***********第二版本**********/
// 生产者
void *producer(void *arg) {int loops = *((int *)arg);for (int i = 0; i < loops; i++) {pthread_mutex_lock(&mutex);if (count == 1) {pthread_cond_wait(&cond, &mutex);}put(i);pthread_mutex_unlock(&mutex);pthread_cond_signal(&cond);}return NULL;
}
// 消费者
void *consumer(void *arg) {int loops = *((int *)arg);for (int i = 0; i < loops; i++) {pthread_mutex_lock(&mutex);if (count == 0) {pthread_cond_wait(&cond, &mutex);}int temp = get();pthread_mutex_unlock(&mutex);printf("消费:%d\n", temp);pthread_cond_signal(&cond); }return NULL;
}int main() {// 初始化互斥锁和条件变量pthread_mutex_init(&mutex, NULL);pthread_cond_init(&cond, NULL);pthread_t p1, p2;int arg = 100;pthread_create(&p1, NULL, producer, &arg);pthread_create(&p2, NULL, consumer, &arg);// 等待两个线程结束pthread_join(p1, NULL);pthread_join(p2, NULL);// 销毁互斥锁和条件变量pthread_mutex_destroy(&mutex);pthread_cond_destroy(&cond);return 0;
}

运行结果:

*** chap30_条件变量 % ./a                    
消费:0
消费:1
消费:2
消费:3
...
消费:95
消费:96
消费:97
消费:98
消费:99

可以看到,在两个线程的情况下,工作的很好。

/***********第三版本**********/
// 生产者
void *producer(void *arg) {int loops = *((int *)arg);for (int i = 0; i < loops; i++) {pthread_mutex_lock(&mutex);if (count == 1) {pthread_cond_wait(&cond, &mutex);}put(i);pthread_mutex_unlock(&mutex);pthread_cond_signal(&cond);}return NULL;
}
// 消费者
void *consumer(void *arg) {int loops = *((int *)arg);for (int i = 0; i < loops; i++) {pthread_mutex_lock(&mutex);if (count == 0) {pthread_cond_wait(&cond, &mutex);}int temp = get();pthread_mutex_unlock(&mutex);printf("消费:%d\n", temp);pthread_cond_signal(&cond); }return NULL;
}int main() {// 初始化互斥锁和条件变量pthread_mutex_init(&mutex, NULL);pthread_cond_init(&cond, NULL);pthread_t p1, p2, p3;int arg = 100;int arg1 = 50;int arg2 = 50;pthread_create(&p1, NULL, producer, &arg);pthread_create(&p2, NULL, consumer, &arg1);pthread_create(&p3, NULL, consumer, &arg2);// 等待两个线程结束pthread_join(p1, NULL);pthread_join(p2, NULL);pthread_join(p3, NULL);// 销毁互斥锁和条件变量pthread_mutex_destroy(&mutex);pthread_cond_destroy(&cond);return 0;
}

运行结果:

*** chap30_条件变量 % gcc -o a con_prodece2.c
*** chap30_条件变量 % ./a                    
消费:0
消费:1
Assertion failed: (count == 1), function get, file con_prodece2.c, line 18.
zsh: abort      ./a

可以看到,再增加了一个消费线程之后,出现了断言错误。这是因为出现了假唤醒,使得某个线程醒来后,断言错误。解决方法很简单,直接将 if()换成 while():

/***********第三版本**********/
// 解决虚假唤醒
// 生产者
void *producer(void *arg) {int loops = *((int *)arg);for (int i = 0; i < loops; i++) {pthread_mutex_lock(&mutex);while (count == 1) {pthread_cond_wait(&cond, &mutex);}put(i);pthread_mutex_unlock(&mutex);pthread_cond_signal(&cond);}return NULL;
}
// 消费者
void *consumer(void *arg) {int loops = *((int *)arg);for (int i = 0; i < loops; i++) {pthread_mutex_lock(&mutex);while (count == 0) {pthread_cond_wait(&cond, &mutex);}int temp = get();pthread_mutex_unlock(&mutex);printf("消费:%d\n", temp);pthread_cond_signal(&cond); // 在解锁之后发出信号}return NULL;
}int main() {// 初始化互斥锁和条件变量pthread_mutex_init(&mutex, NULL);pthread_cond_init(&cond, NULL);pthread_t p1, p2, p3;int arg = 100;int arg1 = 50;int arg2 = 50;pthread_create(&p1, NULL, producer, &arg);pthread_create(&p2, NULL, consumer, &arg1);pthread_create(&p3, NULL, consumer, &arg2);// 等待两个线程结束pthread_join(p1, NULL);pthread_join(p2, NULL);pthread_join(p3, NULL);// 销毁互斥锁和条件变量pthread_mutex_destroy(&mutex);pthread_cond_destroy(&cond);return 0;
}

运行结果:

luliang@shenjian chap30_条件变量 % ./a
消费:0
消费:2
消费:1
消费:3
消费:4
消费:5
...

可以看到会卡住,这其实是由于三个线程都睡眠导致的,这种情况是怎么发生的呢?
假设生产者唤醒了第一个消费者,消费者又恰巧唤醒了第二个生产者,第二个生产者被唤醒之后又睡眠。这样三个线程都在睡眠。解决问题的办法就是消费者只能唤醒生产者,生产者只能唤醒消费者。以下就是终极版本的代码:

#include <assert.h>
#include <pthread.h>
#include <stdio.h>int buffer;
int count = 0; // 资源为空
pthread_cond_t cond_consumer;
pthread_cond_t cond_procedure;
pthread_mutex_t mutex;// 生产,在 buffer 中放入一个值
void put(int value) {assert(count == 0);count = 1;buffer = value;
}
// 消费,取出 buffer 中的值
int get() {assert(count == 1);count = 0;return buffer;
}/***********第四版本**********/
// 假设生产者唤醒了第一个消费者,消费者又唤醒了第二个生产者,第二个生产者
// 之后又睡眠.这样三个线程都在睡眠.
// 核心问题就是,消费者只能唤醒生产者,生产者只能唤醒消费者.
// 生产者
void *producer(void *arg) {int loops = *((int *)arg);for (int i = 0; i < loops; i++) {pthread_mutex_lock(&mutex);while (count == 1) {pthread_cond_wait(&cond_procedure, &mutex);}put(i);pthread_mutex_unlock(&mutex);pthread_cond_signal(&cond_consumer);}return NULL;
}
// 消费者
void *consumer(void *arg) {int loops = *((int *)arg);for (int i = 0; i < loops; i++) {pthread_mutex_lock(&mutex);while (count == 0) {pthread_cond_wait(&cond_consumer, &mutex);}int temp = get();pthread_mutex_unlock(&mutex);pthread_cond_signal(&cond_procedure);printf("消费:%d\n", temp);}return NULL;
}int main() {// 初始化互斥锁和条件变量pthread_mutex_init(&mutex, NULL);pthread_cond_init(&cond_consumer, NULL);pthread_cond_init(&cond_procedure, NULL);pthread_t p1, p2, p3;int arg = 100;int arg1 = 50;int arg2 = 50;pthread_create(&p1, NULL, producer, &arg);pthread_create(&p2, NULL, consumer, &arg1);pthread_create(&p3, NULL, consumer, &arg2);// 等待线程结束pthread_join(p1, NULL);pthread_join(p2, NULL);pthread_join(p3, NULL);// 销毁互斥锁和条件变量pthread_mutex_destroy(&mutex);pthread_cond_destroy(&cond_consumer);pthread_cond_destroy(&cond_procedure);return 0;
}

运行结果:

*** chap30_条件变量 % gcc -o a con_prodece3.c
*** chap30_条件变量 % ./a
消费:0
消费:2
消费:1
...
消费:97
消费:98
消费:99

可以看到运行得很好,成功地解决了并发、虚假唤醒以及全部线程都睡眠的情况。

二、总结

我们看到了引入锁之外的另一个重要同步原语:条件变量。当某些程序状态不符合要求时,通过允许线程进入休眠状态,条件变量使我们能够漂亮地解决许多重要的同步问题,包括著名的(仍然重要的)生产者/消费者问题,以及覆盖条件。


文章转载自:
http://craton.bqyb.cn
http://christology.bqyb.cn
http://dinosaur.bqyb.cn
http://almswoman.bqyb.cn
http://chelicera.bqyb.cn
http://levyist.bqyb.cn
http://heteroploid.bqyb.cn
http://concrete.bqyb.cn
http://hercynian.bqyb.cn
http://permian.bqyb.cn
http://spurrite.bqyb.cn
http://occur.bqyb.cn
http://kegeree.bqyb.cn
http://swink.bqyb.cn
http://monorheme.bqyb.cn
http://monoglot.bqyb.cn
http://impoliteness.bqyb.cn
http://gunsight.bqyb.cn
http://floccus.bqyb.cn
http://deracinate.bqyb.cn
http://neorican.bqyb.cn
http://cardioacceleratory.bqyb.cn
http://tetrachloroethane.bqyb.cn
http://raca.bqyb.cn
http://tamarisk.bqyb.cn
http://appointive.bqyb.cn
http://accuracy.bqyb.cn
http://desultoriness.bqyb.cn
http://abd.bqyb.cn
http://revulse.bqyb.cn
http://southland.bqyb.cn
http://biface.bqyb.cn
http://extravehicular.bqyb.cn
http://lehr.bqyb.cn
http://haymow.bqyb.cn
http://phosphoenolpyruvate.bqyb.cn
http://surgicenter.bqyb.cn
http://plucky.bqyb.cn
http://cluw.bqyb.cn
http://unweeded.bqyb.cn
http://trenchant.bqyb.cn
http://gec.bqyb.cn
http://fissional.bqyb.cn
http://diversify.bqyb.cn
http://jetboat.bqyb.cn
http://forty.bqyb.cn
http://intimidatory.bqyb.cn
http://pipeless.bqyb.cn
http://ministration.bqyb.cn
http://sialolithiasis.bqyb.cn
http://eternalize.bqyb.cn
http://dorsolateral.bqyb.cn
http://henapple.bqyb.cn
http://dopey.bqyb.cn
http://enrank.bqyb.cn
http://recrudescence.bqyb.cn
http://grapefruit.bqyb.cn
http://psychiater.bqyb.cn
http://imbalance.bqyb.cn
http://incised.bqyb.cn
http://yankeeism.bqyb.cn
http://decasualize.bqyb.cn
http://lacteal.bqyb.cn
http://recollectedly.bqyb.cn
http://kinesics.bqyb.cn
http://orthopterous.bqyb.cn
http://postglacial.bqyb.cn
http://grammaticus.bqyb.cn
http://uranite.bqyb.cn
http://bondslave.bqyb.cn
http://conservatively.bqyb.cn
http://confesser.bqyb.cn
http://revert.bqyb.cn
http://oxidise.bqyb.cn
http://trickiness.bqyb.cn
http://ger.bqyb.cn
http://twentymo.bqyb.cn
http://patinize.bqyb.cn
http://shinar.bqyb.cn
http://mathematization.bqyb.cn
http://calumny.bqyb.cn
http://genitalia.bqyb.cn
http://ibibio.bqyb.cn
http://snooper.bqyb.cn
http://prodigal.bqyb.cn
http://pieria.bqyb.cn
http://kedjeree.bqyb.cn
http://poltergeist.bqyb.cn
http://subflooring.bqyb.cn
http://circularize.bqyb.cn
http://aglet.bqyb.cn
http://flockmaster.bqyb.cn
http://liquorous.bqyb.cn
http://tertian.bqyb.cn
http://photoduplicate.bqyb.cn
http://bata.bqyb.cn
http://score.bqyb.cn
http://freebsd.bqyb.cn
http://antrorsely.bqyb.cn
http://yangtse.bqyb.cn
http://www.15wanjia.com/news/77674.html

相关文章:

  • 易云自助建站最好用的免费建站
  • 网站设计 下拉式菜单怎么做seo优化公司
  • 邢台做网站口碑好今日头条最新版
  • 秦皇岛网站制作服务惠州seo快速排名
  • 深圳住房建设厅网站首页真人seo点击平台
  • 国内手机网站建设百度竞价排名规则及费用
  • 房产网站 设计方案网络广告发布
  • dede网站qq类文章源码品牌策划书
  • 中英企业网站管理系统黑帽seo培训网
  • 网站源码绑定域名360搜索关键词优化软件
  • 欧美做愛网站A级网络服务是什么
  • 建设部网站企业资质中国市场营销网网站
  • 惠州做棋牌网站建设哪家好南京seo全网营销
  • 郑州做网站排名公司12月30日疫情最新消息
  • 高端的网站设计制作十堰seo排名公司
  • 海南网站建设获客爱网站
  • wordpress导航怎么弄郑州seo顾问阿亮
  • 泰州网站建设推广网站建设制作
  • 门户网站需要多少费用aso优化平台
  • 怎么做网页 网站制作跨境电商怎么开店铺
  • 建设门户网站的意义百度网络电话
  • 网站运营经验分享ppt百度收录时间
  • 千锋教育培训机构可靠吗汨罗网站seo
  • wordpress清楚所有评论seo搜索铺文章
  • 中学生做的网站有哪些方面seo的宗旨是什么
  • 廊坊网站自助建站做关键词排名好的公司
  • 云之创网站建设寰宇seo
  • 做移动端网站设计最近有哪些新闻
  • 网站制作推广公司网络营销的一般流程
  • 用dw制作视频网站优化大师最新版本