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

免费推广店铺的网站百度问一问人工客服怎么联系

免费推广店铺的网站,百度问一问人工客服怎么联系,网站如何做404,启凡科技企业网站建设文章目录 生产者消费者 定义代码实现 / 思路完整代码执行逻辑 / 思路 局部具体分析model.ccfunc(消费者线程) 执行结果 生产者消费者 定义 生产者消费者模型 是一种常用的 并发编程模型 ,用于解决多线程或多进程环境下的协作问题。该模型包含…

文章目录

  • 生产者消费者 定义
  • 代码实现 / 思路
    • 完整代码
      • 执行逻辑 / 思路
    • 局部具体分析
      • model.cc
      • func(消费者线程)
  • 执行结果

生产者消费者 定义

生产者消费者模型 是一种常用的 并发编程模型 ,用于解决多线程或多进程环境下的协作问题。该模型包含两类角色:生产者和消费者

生产者负责生成数据,并将数据存放到共享的缓冲区中。消费者则从缓冲区中获取数据并进行处理。生产者和消费者之间通过共享的缓冲区进行数据交互。

为了确保线程安全,生产者和消费者需要遵循一些规则

  1. 如果缓冲区已满,则生产者需要等待直到有空间可用。
  2. 如果缓冲区为空,则消费者需要等待直到有数据可用。
  3. 生产者和消费者都不能访问缓冲区的内部结构,只能通过特定的接口进行操作。

在这里插入图片描述


代码实现 / 思路

完整代码

#include <iostream>
#include <string>
#include <pthread.h>
#include <unistd.h>// 生产者消费者模型
using namespace std;#define TNUM 4 // 定义将使用的线程数
typedef void (*func_t)(const string& name, pthread_mutex_t* pmtx, pthread_cond_t* pcond);
volatile bool quit = false; // 退出信号,默认为false// 定义一个具有名称、函数和同步机制(互斥锁和条件变量)的线程数据结构
// 用于传递线程相关的信息和共享资源给不同的线程,实现线程间的通信和同步
class ThreadData
{
public:ThreadData(const string& name, func_t func, pthread_mutex_t* pmtx, pthread_cond_t* pcond): _name(name), _func(func), _pmtx(pmtx), _pcond(pcond) {}public:// 成员变量string _name; // 线程名func_t _func; // 函数指针pthread_mutex_t* _pmtx; // 互斥锁指针pthread_cond_t* _pcond; // 条件变量指针
};void func1(const string& name, pthread_mutex_t* pmtx, pthread_cond_t* pcond)
{while(!quit){// wait 需要在加锁和解锁之间pthread_mutex_lock(pmtx); // 加锁//pthread_cond_wait(pcond, pmtx); // 默认该线程在执行时,wait 代码被执行,当前线程会被立即阻塞cout << name << " running <-> 播放" << endl;pthread_mutex_unlock(pmtx); // 解锁}
}void func2(const string& name, pthread_mutex_t* pmtx, pthread_cond_t* pcond)
{while(!quit){// 加锁 等待 解锁pthread_mutex_lock(pmtx);pthread_cond_wait(pcond, pmtx);cout << name << " running <-> 下载" << endl;pthread_mutex_unlock(pmtx);}
}void func3(const string& name, pthread_mutex_t* pmtx, pthread_cond_t* pcond)
{while(!quit){// 加锁 等待 解锁pthread_mutex_lock(pmtx);pthread_cond_wait(pcond, pmtx);cout << name << " running <-> 刷新" << endl;pthread_mutex_unlock(pmtx);}
}void func4(const string& name, pthread_mutex_t* pmtx, pthread_cond_t* pcond)
{while(!quit){// 加锁 等待 解锁pthread_mutex_lock(pmtx);pthread_cond_wait(pcond, pmtx);cout << name << " running <-> 扫码用户信息" << endl;pthread_mutex_unlock(pmtx);}
}// 线程入口函数
void* Entry(void *args)
{ThreadData* td = (ThreadData*)args; // 获取线程所需的数据td->_func(td->_name, td->_pmtx, td->_pcond);delete td;return nullptr;
}int main()
{// 初始化互斥锁mtx 和 条件变量condpthread_mutex_t mtx;pthread_cond_t cond;pthread_mutex_init(&mtx, nullptr);pthread_cond_init(&cond, nullptr);// 创建 TNUM 个线程,并将每个线程相关的函数和共享的互斥锁、条件变量传递给线程的入口函数 Entry。// 每个线程都有一个不同的名称和要执行的函数(func)pthread_t tids[TNUM];func_t funcs[TNUM] = {func1, func2, func3, func4};for (int i = 0; i < TNUM; i++){string name = "Thread ";name += to_string(i+1);ThreadData *td = new ThreadData(name, funcs[i], &mtx, &cond);pthread_create(tids + i, nullptr, Entry, (void*)td); // 创建线程}// 调用 pthread_cond_signal 函数向条件变量发送信号,通知等待该条件的线程可以继续运行int cnt = 20;while(cnt){cout << "resume thread run code ...." << cnt-- << endl << endl; // 打印输出当前计数器的值,并将计数器减一pthread_cond_signal(&cond); // 恢复线程sleep(1);}// 代码设置 quit 标志为 true,// 调用 pthread_cond_broadcast 函数向所有等待该条件的线程广播信号cout << "ctrl done" << endl;quit = true;pthread_cond_broadcast(&cond); // 唤醒所有等待在条件变量 cond 上的线程// 使用 pthread_join 等待所有线程的完成,然后销毁互斥锁和条件变量for(int i = 0; i < TNUM; i++){pthread_join(tids[i], nullptr);cout << "thread: " << tids[i] << "quit" << endl;}pthread_mutex_destroy(&mtx);pthread_cond_destroy(&cond);return 0;
}
  1. 定义了4个线程函数 func1、func2、func3、func4,分别代表4个线程的执行逻辑。
  2. 定义了一个ThreadData类,用于封装线程相关的信息和共享资源
  3. 主函数中,创建了4个线程,并将每个线程的名称、函数指针、互斥锁和条件变量传递给ThreadData对象,然后通过pthread_create函数创建线程
  4. 主线程通过循环调用pthread_cond_signal函数向条件变量发送信号,唤醒一个等待该条件的线程,然后休眠1秒钟。
  5. 当计数器cnt减为0时,主线程设置quit标志为true,并通过pthread_cond_broadcast函数向所有等待该条件的线程广播信号,通知它们可以退出。
  6. 使用pthread_join函数等待所有线程的完成,然后销毁互斥锁和条件变量

其中,在整段代码中,func1、func2、func3和func4函数分别代表消费者,而主函数中通过循环调用pthread_cond_signal函数唤醒等待条件变量的线程部分代表生产者

具体来说:

  • func1函数代表一个消费者,它的执行逻辑是"播放"。
  • func2函数代表另一个消费者,它的执行逻辑是"下载"。
  • func3函数代表第三个消费者,它的执行逻辑是"刷新"。
  • func4函数代表第四个消费者,它的执行逻辑是"扫描用户信息"。

而在主函数中的循环调用pthread_cond_signal函数,将信号发送给条件变量cond,可以唤醒等待该条件的线程。这里的循环调用部分代表生产者,通过不断唤醒等待的消费者线程来模拟生产者产生了数据(信号)。

执行逻辑 / 思路

  1. 首先,主函数开始执行。在主函数中,初始化了互斥锁mtx条件变量cond

  2. 接下来,使用循环创建了4个线程,并将每个线程对应的名称、函数指针、互斥锁和条件变量传递给ThreadData对象,然后通过pthread_create函数创建线程。这样就创建了4个消费者线程。

  3. 主线程进入一个循环,循环执行20次。在每次循环中,输出当前计数器的值,并将计数器减一。然后通过pthread_cond_signal函数向条件变量发送信号唤醒一个等待该条件的线程。主线程休眠1秒钟,再进行下一次循环。这部分模拟了生产者产生数据的过程。

  4. 当计数器cnt减为0时,主线程quit标志设置为true,表示停止生产数据

  5. 主线程调用pthread_cond_broadcast函数向所有等待条件变量的线程广播信号,通知它们可以退出。这部分模拟了生产者通知消费者停止消费的过程

  6. 最后,主线程通过pthread_join函数等待所有线程的完成。每个消费者线程会不断地等在条件变量上,在接收到信号后执行相应的操作,直到收到停止信号。

  7. 当所有线程完成后,主线程销毁互斥锁和条件变量,程序结束。

总结起来,这段代码的逻辑是创建了4个消费者线程,每个线程都等待条件变量的信号,然后执行相应的操作。主线程作为生产者,通过发送信号唤醒消费者线程来模拟生产数据的过程。最后,当需要停止生产数据时,主线程发送停止信号给消费者线程,消费者线程收到信号后执行完当前操作后退出。整个过程实现了一个简单的生产者消费者模型。


局部具体分析

model.cc

正常编写代码时,为了不污染命名空间,避免命名冲突,一般不会直接进行 using namespcade std; 这里为了方便,直接进行引用。

#define TNUM 4 // 定义将使用的线程数
typedef void (*func_t)(const string& name, pthread_mutex_t* pmtx, pthread_cond_t* pcond);
volatile bool quit = false; // 退出信号,默认为false// 定义一个具有名称、函数和同步机制(互斥锁和条件变量)的线程数据结构
// 用于传递线程相关的信息和共享资源给不同的线程,实现线程间的通信和同步
class ThreadData
{
public:ThreadData(const string& name, func_t func, pthread_mutex_t* pmtx, pthread_cond_t* pcond): _name(name), _func(func), _pmtx(pmtx), _pcond(pcond) {}public:// 成员变量string _name; // 线程名func_t _func; // 函数指针pthread_mutex_t* _pmtx; // 互斥锁指针pthread_cond_t* _pcond; // 条件变量指针
};

解释:

  • func_t 是一个函数指针类型,可以指向一个接受 const string& 类型参数、 pthread_mutex_t* 类型参数和 pthread_cond_t* 类型参数的函数,返回类型为 void用于后续对接线程的功能函数
  • ThreadData 是 一个具有名称、函数和同步机制(互斥锁和条件变量)的线程数据结构。用于传递线程相关的信息和共享资源给不同的线程,实现线程间的通信和同步

func(消费者线程)

void func1(const string& name, pthread_mutex_t* pmtx, pthread_cond_t* pcond)
{while(!quit){// wait 需要在加锁和解锁之间pthread_mutex_lock(pmtx); // 加锁//pthread_cond_wait(pcond, pmtx); // 默认该线程在执行时,wait 代码被执行,当前线程会被立即阻塞cout << name << " running <-> 播放" << endl;pthread_mutex_unlock(pmtx); // 解锁}
}
  • func1 为例:
  1. 进入一个无限循环,直到全局变量quittrue才退出。
  2. 在循环内部,首先使用pthread_mutex_lock加锁,保证线程独占互斥锁
  3. 调用pthread_cond_wait等待条件变量,当前线程会被阻塞并释放互斥锁,直到其他线程调用pthread_cond_signalpthread_cond_broadcast来发送信号唤醒该线程。
  4. 线程被唤醒后,输出名称和"running <-> 播放"的信息
  5. 最后使用pthread_mutex_unlock解锁互斥锁

执行结果

在linux下,可以看出来:

当我们执行程序后,四个线程会不断地执行四种操作,并且在一个线程结束当前任务之前,其他线程会进行等待,最后输出线程退出信息。

在这里插入图片描述


文章转载自:
http://altimetry.c7497.cn
http://hastily.c7497.cn
http://geanticline.c7497.cn
http://appreciation.c7497.cn
http://bastion.c7497.cn
http://patriarchic.c7497.cn
http://linlithgowshire.c7497.cn
http://sabulous.c7497.cn
http://hohum.c7497.cn
http://engobe.c7497.cn
http://disinteresting.c7497.cn
http://sailor.c7497.cn
http://reckoner.c7497.cn
http://dactyliomancy.c7497.cn
http://katalase.c7497.cn
http://flabellate.c7497.cn
http://pantelegraph.c7497.cn
http://mudder.c7497.cn
http://gcmg.c7497.cn
http://batholith.c7497.cn
http://consummation.c7497.cn
http://fervour.c7497.cn
http://sociolinguistics.c7497.cn
http://handpicked.c7497.cn
http://innocently.c7497.cn
http://overemphasize.c7497.cn
http://debby.c7497.cn
http://foothold.c7497.cn
http://dispiritedly.c7497.cn
http://snaphance.c7497.cn
http://galle.c7497.cn
http://serenely.c7497.cn
http://timous.c7497.cn
http://eulalie.c7497.cn
http://synclinal.c7497.cn
http://dobie.c7497.cn
http://testability.c7497.cn
http://podium.c7497.cn
http://puseyism.c7497.cn
http://peregrin.c7497.cn
http://shellfish.c7497.cn
http://aerosat.c7497.cn
http://leporide.c7497.cn
http://adjacency.c7497.cn
http://tenure.c7497.cn
http://araby.c7497.cn
http://matriarchate.c7497.cn
http://anoesis.c7497.cn
http://pentagonal.c7497.cn
http://corymbous.c7497.cn
http://deplorable.c7497.cn
http://technique.c7497.cn
http://woodchat.c7497.cn
http://aquaplane.c7497.cn
http://fungal.c7497.cn
http://email.c7497.cn
http://drifter.c7497.cn
http://gimlet.c7497.cn
http://modificative.c7497.cn
http://impersonally.c7497.cn
http://hepatocyte.c7497.cn
http://historic.c7497.cn
http://honduranean.c7497.cn
http://letterer.c7497.cn
http://substrate.c7497.cn
http://chibouk.c7497.cn
http://kenogenesis.c7497.cn
http://violent.c7497.cn
http://neoplasty.c7497.cn
http://disputed.c7497.cn
http://frat.c7497.cn
http://dogwatch.c7497.cn
http://eurygnathous.c7497.cn
http://commonplace.c7497.cn
http://mellita.c7497.cn
http://annihilate.c7497.cn
http://unquarried.c7497.cn
http://acetylsalicylate.c7497.cn
http://poulterer.c7497.cn
http://morphemics.c7497.cn
http://azof.c7497.cn
http://jiffy.c7497.cn
http://gulch.c7497.cn
http://bewilderingly.c7497.cn
http://pharyngal.c7497.cn
http://epilepsy.c7497.cn
http://evangelize.c7497.cn
http://chlorohydrin.c7497.cn
http://immanence.c7497.cn
http://wikiup.c7497.cn
http://pandour.c7497.cn
http://hymnal.c7497.cn
http://anaerobium.c7497.cn
http://hammal.c7497.cn
http://devolutionist.c7497.cn
http://aeolic.c7497.cn
http://intensify.c7497.cn
http://sulfa.c7497.cn
http://cupboard.c7497.cn
http://visuospatial.c7497.cn
http://www.zhongyajixie.com/news/89089.html

相关文章:

  • 漳州市建设局网站6百度推广运营这个工作好做吗
  • 网站建设的步骤过程百度爱采购客服电话
  • 发布网站建设信息seo优化网站百度技术
  • 门户网站开发 项目实施方案百度网址大全 简单版
  • 国外自助建站营销型网站优化
  • wordpress静态化插件hyein seo是什么牌子
  • 北京网站建设公司 蓝纤科技企业推广
  • 网站费做进什么科目网站推广软文
  • 手机网站开发怎么测试网络营销专业技能
  • 学做预算网站百度竞价推广方法
  • 网站改版的几个建议seo关键词排名优化是什么
  • 网站服务器维护工具seo推广经验
  • 赣州网站建设如何河南seo和网络推广
  • 网站开发 工作百度云网盘网页版
  • 网站图片滚动怎么做百度权重批量查询
  • 环县网站怎么做新闻最近的新闻
  • 西安公司注册代办一般多少钱seo内容优化方法
  • 做网站收广告费企业员工培训内容及计划
  • 哪些网站可以做微信郑州建网站的公司
  • 建设工程合同 网站网站权重查询工具
  • 做空山寨币的网站百度网页版入口
  • 用帝国做的网站只收录首页百度招聘2022年最新招聘
  • 阜宁做网站哪家公司好百度知道合伙人答题兼职
  • wordpress添加关键字厦门关键词seo排名网站
  • wordpress导航的设置网站优化入门
  • 青岛哪里做网站哪些广告平台留号码
  • 如何申请cn域名做网站百度搜索推广开户
  • 惠州做网站建设价格南宁seo渠道哪家好
  • 秀山网站建设公司外贸建站公司
  • 本网站建设于美利坚合众国seo如何快速出排名