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

企业做网站和宣传册的作用昆明企业为什么要做网站

企业做网站和宣传册的作用,昆明企业为什么要做网站,网站续费合同,wordpress的插件下载目录 一、问题引入 二、实现线程同步的方案——条件变量 1、常用接口&#xff1a; 2、使用示例 一、问题引入 我们再次看看上次讲到的多线程抢票的代码&#xff1a;这次我们让一个线程抢完票之后不去做任何事。 #include <iostream> #include <unistd.h> #inc…

目录

一、问题引入

二、实现线程同步的方案——条件变量

1、常用接口:

2、使用示例


一、问题引入

我们再次看看上次讲到的多线程抢票的代码:这次我们让一个线程抢完票之后不去做任何事。

#include <iostream>
#include <unistd.h>
#include <cstring>
#include <time.h>
#include <pthread.h>using namespace std;
#define THREAD_NUM 5class threaddata
{
public:threaddata(const string &s, pthread_mutex_t *m): name(s), mtx(m){}public:string name;pthread_mutex_t *mtx;
};int ticket = 100;void *getticket(void *arg)
{threaddata *td = (threaddata *)arg;while (true){pthread_mutex_lock(td->mtx); if (ticket > 0)              {usleep(rand() % 10000);cout << td->name << ":"<< " " << ticket << endl;ticket--;pthread_mutex_unlock(td->mtx); }else{pthread_mutex_unlock(td->mtx); break;}}delete td;return nullptr;
}int main()
{pthread_mutex_t mtx;pthread_mutex_init(&mtx, nullptr);pthread_t t[THREAD_NUM];for (int i = 0; i < THREAD_NUM; i++){string name = "thread ";name += to_string(i + 1);threaddata *td = new threaddata(name, &mtx);pthread_create(t + i, nullptr, getticket, (void *)td);}for (int i = 0; i < THREAD_NUM; i++)pthread_join(t[i], nullptr);pthread_mutex_destroy(&mtx);return 0;
}

运行结果:

我们这就发现了一个问题,对于抢票系统,我们看到的是只有一个线程5在一直连续抢票,没有其他的线程。这很不合理。

这是因为如果个别线程的竞争力特别强,每次都能够申请到锁,但申请到锁之后什么也不做,所以在我们看来这个线程就一直在申请锁和释放锁,那么它就可以一直抢票。这就可能导致其他线程长时间竞争不到锁,造成了其他线程的饥饿问题(无法抢票)。虽然,你是拿到锁后再去访问临界资源,并且最后还释放了锁,由于竞争能力太强,可以一直拿到锁,这没有错,但这不合理。

为了解决这个问题,我们增加一个限制:当一个线程释放锁后,这个线程不能立马再次申请锁,该线程必须排到这个锁的资源等待队列的最后。这样,我们就有了线程同步:我们在保证数据安全的情况下让这些线程按照一定的顺序进行临界资源的访问,这就是线程同步。

竞态条件:因为时序问题,而导致程序异常,我们称为竞态条件。

二、实现线程同步的方案——条件变量

当一个线程互斥地访问某个变量时,它可能发现在其他线程改变状态之前,它什么也做不了

例如一个线程访问队列时,发现队列为空,它只能等待,直到其他线程将一个节点添加到队列中。这种情况就需要用到条件变量。

1、常用接口:

1、条件变量的定义和初始化

​
NAMEpthread_cond_destroy, pthread_cond_init - destroy and initialize condition variablesSYNOPSIS#include <pthread.h>//销毁int pthread_cond_destroy(pthread_cond_t *cond);//初始化int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);//全局和静态变量初始化pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

2、线程等待临界资源: 

pthread_cond_wait 功能:一就是让线程在特定的条件变量下等待,二就是让线程在等待时释放对应的互斥锁。当线程被唤醒时,该函数会帮助我们线程获取锁。

#include <pthread.h>
//特定时间阻塞等待
int pthread_cond_timedwait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex,const struct timespec *restrict abstime);
//等待
int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);

 3、唤醒线程去访问临界资源

#include <pthread.h>
// 唤醒所有等待的线程
int pthread_cond_broadcast(pthread_cond_t *cond);// 唤醒一个线程
int pthread_cond_signal(pthread_cond_t *cond);

注:1、条件变量通常需要配合互斥锁一起使用。

2、条件变量的使用:一个线程等待条件变量的条件成立而被挂起;另一个线程使条件成立后唤醒等待的线程。

3、等待的时候往往是在临界区内等待的。(加锁与解锁之间的区域进行等待)

4、线程被唤醒,是在之前进行等待的地方被唤醒。

2、使用示例

有了线程同步,我们就可以改进我们之前的抢票系统的代码:

#include <iostream>
#include <string>
#include <time.h>
#include <unistd.h>
#include <pthread.h>using namespace std;
#define THREADNUM 3
typedef void *(*func)(void *argc);class threaddata
{
public:threaddata(pthread_mutex_t *mtx, pthread_cond_t *cond, const string &name): mtx_(mtx), cond_(cond), name_(name){}public:pthread_mutex_t *mtx_;pthread_cond_t *cond_;string name_;
};int ticket = 100;void *getticket(void *arg)
{threaddata *td = (threaddata *)arg;while (true){pthread_mutex_lock(td->mtx_);pthread_cond_wait(td->cond_, td->mtx_); // 在加锁和解锁之间进行等待if (ticket > 0){usleep(rand() % 10000);cout << td->name_ << ":"<< " " << ticket << endl;ticket--;pthread_mutex_unlock(td->mtx_);}else{pthread_mutex_unlock(td->mtx_);break;}}delete td;return nullptr;
}void *fun1(void *arg)
{threaddata *td = (threaddata *)arg;while (true){getticket((void *)td);sleep(1);}
}void *fun2(void *arg)
{threaddata *td = (threaddata *)arg;while (true){getticket((void *)td);sleep(1);}
}void *fun3(void *arg)
{threaddata *td = (threaddata *)arg;while (true){getticket((void *)td);sleep(1);}
}int main()
{srand((unsigned long)time(nullptr) ^ getpid() ^ 433);pthread_mutex_t mtx;pthread_cond_t cond;pthread_mutex_init(&mtx, nullptr);pthread_cond_init(&cond, nullptr);pthread_t t[THREADNUM];func fun[THREADNUM] = {fun1, fun2, fun3};for (int i = 0; i < THREADNUM; i++){string name = "thread ";name += to_string(i + 1);threaddata *td = new threaddata(&mtx, &cond, name);pthread_create(t + i, nullptr, fun[i], (void *)td);}sleep(5);while (true){pthread_cond_signal(&cond);sleep(1);}for (int i = 0; i < THREADNUM; i++)pthread_join(t[i], nullptr);pthread_mutex_destroy(&mtx);pthread_cond_destroy(&cond);return 0;
}

如果我们每次都想将在该条件变量下等待的所有线程进行唤醒,可以将代码中的pthread_cond_signal函数改为pthread_cond_broadcast函数。 

此时我们会发现唤醒这三个线程时具有明显的顺序性,因为这些线程启动时默认都会在该条件变量下去等待,而我们每次都唤醒的是在当前条件变量下等待的头部线程,当该线程执行完代码后会继续排到等待队列的尾部进行等待。

http://www.yayakq.cn/news/509094/

相关文章:

  • 网站实名认证要钱吗做手机软件需要学什么
  • 苏州建行网站广东新闻联播直播在线观看
  • 中国建设银行网站多少企业网站分析报告
  • 网站建设服务器有哪些crm销售
  • 校园文化网站建设一屏展示网站
  • p2p网站制作价格做有网被视频网站有哪些
  • 如何做监控网站建设网站的方案
  • 济南 网站优化seo软件哪个好
  • 上海的建设网站知名的wordpress博客
  • 做网站业务员如何跟客户沟通长春纯手工seo
  • 深圳网站建设..wordpress 自动分页插件
  • 如何做虚拟币交易网站客户关系管理crm课程
  • 如何拿qq空间做网站app开发公司官网
  • 商业网站教程网络营销方式有哪几种有哪些
  • 有没有什么做h5的网站家装业务员怎么做网站营销
  • 网站seo搜索jsp网站开发视频
  • dw做链接网站无法显示该页面天猫网站建设分析
  • 电脑手机网站制作直接用ip做网站
  • 网站建设费用 百度文库如何用Python网站开发
  • 浙江省职业能力建设处网站wordpress更新之后字体发生变化
  • 泉州建站模板系统小程序商城页面设计
  • 建网站培训机构在线培训平台有哪些
  • 怎么安装免费的wordpress主题南昌seo建站
  • ps做图游戏下载网站有哪些内容茂名制作网站软件
  • 枣庄学习建设网站培训友情链接你会回来感谢我
  • 莱芜装修网站颜色搭配的网站
  • 威海企业网站建设ppt做的最好的网站
  • 如何用个门户网站做销售门户网站开发需求文档
  • 做网站是需要多少钱沈阳网站建设优化企业
  • 辽阳网站建设多少钱哈尔滨如何快速建站