ssRender引擎 Plugin实现生产者消费者模型

概述

本次工程使用Plugin插件实现实现生产者消费者模型,创建两个线程,分别用于生产、购买;产品数量的上限为6;两个线程分别对其进行设置,当数量达到上限6时,生产者暂停生产,等待消费者购买;当数量达到下限0时,消费者暂停购买,等待生产者生产。

效果

在这里插入图片描述

创建属性

这里我们创建4个属性分别用于存放数量、显示文字

		SSR_PLUGIN_PROPERTY("Thread", "BufferSize", TYPE_INT, "6", 0, 6, "BufferSize", PCT_TextBoxBind) //产品数量
		SSR_PLUGIN_PROPERTY("Sum", "ProducerSum", TYPE_INT, " 0", 0, 65535, "ProducerSum", PCT_TextBoxBind) //生产总量
		SSR_PLUGIN_PROPERTY("Sum", "ConsumerSum", TYPE_INT, " 0",0 , 65535, "ConsumerSum", PCT_TextBoxBind) //购买总量
		SSR_PLUGIN_PROPERTY("Text", "Text", TYPE_INT, " ", , , "Text", PCT_TextBox) //存放文字,显示当前操作

		int product_quantity = 0;          // 当前库存容量
		int BUFFER_SIZE = 6;                //  最大数量
		int P_Sum = 0, C_Sum = 0;      //  计算生产/消费总数量
	
	
		//接收返回值,用作判断:线程是否创建成功
		int ret_p;
		int ret_c;
	
		pthread_t producer_thread;                //生产者ID
		pthread_t consumer_thread;                //消费者ID
	
		pthread_mutex_t mutex;                        //互斥锁
		pthread_cond_t producer_cond;        //生产者条件变量
		pthread_cond_t consumer_cond;   //消费者条件变量

创建线程

这里我们创建2个线程,分别是Producer(生产者)、Consumer(消费者),并对其设置具体操作。

  1. 消费者、生产者 不能同时拥有锁(mutex),当生产者对资源(product_quantity)进行访问设置时,生产者拥有锁,其余线程等待生产者设置完成后通知或等待解锁。
  2. 当数量达到上限6时,生产者暂停生产,等待消费者购买;当数量达到下限0时,消费者暂停购买,等待生产者生产
  3. 每次线程执行时,向Text属性输出当前操作(购买/生产 1个),ProducerSum、ConsumerSum输出生产/购买总数。
  4. 通过sleep控制间隔时间
SSRObject* UserPluginDLL::createSSRObject()
{
#ifdef TYPE_PLUGIN_DATA
	SSRObject* ssrObj = new UserPluginDLL;
#else
	SSRObject* ssrObj = new SSRObject;
#endif

	ssrObj->m_ssRptr_plugin = this;
	ssrObj->m_ssRtype = OBJECT_TYPE_PLUGIN;


	pthread_mutex_init(&mutex, NULL);        //初始化



	ret_p = pthread_create(&producer_thread, NULL, Producer, (void *)ssrObj);// 创建生产者线程
	if (ret_p != 0) {
		Common::printlog(LOG_LEV_ERROR, "Error____Producer! \n");
	}

	ret_c = pthread_create(&consumer_thread, NULL, Consumer, (void *)ssrObj);// 创建消费者线程
	if (ret_c != 0) {
		Common::printlog(LOG_LEV_ERROR, "Error____Consumer! \n");
	}

	return ssrObj;
}
SSR_PLUGIN_DEFINITION(UserPluginDLL)//调用此宏定义,创建预定义函数接口

void* Producer(void* arg)
{

	SSRObject* ssrObject = (SSRObject*)arg;
	//int count = 0;//ssTools::Common::int2str(count);
	UserPluginDLL* dataSource = (UserPluginDLL*)ssrObject->m_ssRptr_plugin;


	while (1) {

		pthread_mutex_lock(&dataSource->mutex);        // 加锁

		// 如果库存已满,等待购买
		while (dataSource->product_quantity >= dataSource->BUFFER_SIZE) {
			Common::printlog(LOG_LEV_ERROR, "Wait_____Consumer……\n");
			pthread_cond_wait(&dataSource->producer_cond, &dataSource->mutex);
			pthread_mutex_unlock(&dataSource->mutex);// 解锁
			Sleep(1500);

		}

		Common::printlog(LOG_LEV_ERROR, "当前数量:%d\n", dataSource->product_quantity);
		// 生产商品
		dataSource->product_quantity++;
		dataSource->P_Sum++;
		Common::printlog(LOG_LEV_ERROR, "生产1个\n");
		dataSource->m_renderEngine->getPropertySystem()->setPropertyValue(ssrObject, "ProducerSum", Common::int2str(dataSource->P_Sum));
		dataSource->m_renderEngine->getPropertySystem()->setPropertyValue(ssrObject, "BufferSize", Common::int2str(dataSource->product_quantity));
		dataSource->m_renderEngine->getPropertySystem()->setPropertyValue(ssrObject, "Text", "生产1个");
		pthread_mutex_unlock(&dataSource->mutex);// 解锁
		pthread_cond_signal(&dataSource->consumer_cond);// 发送信号,唤醒等待的线程
		Sleep(2000);

	}

	return ssrObject;
}
void* Consumer(void* arg)
{
	SSRObject* ssrObject = (SSRObject*)arg;
	UserPluginDLL* dataSource = (UserPluginDLL*)ssrObject->m_ssRptr_plugin;

	while (1) {

		pthread_mutex_lock(&dataSource->mutex);        // 加锁
		
		// 如果库存为空,等待生产
		while (dataSource->product_quantity <= 0) {
			Common::printlog(LOG_LEV_ERROR, "Wait_____Producer————\n");
			pthread_cond_wait(&dataSource->consumer_cond, &dataSource->mutex);
			pthread_mutex_unlock(&dataSource->mutex);// 解锁
			Sleep(1000);
		}

		Common::printlog(LOG_LEV_ERROR, "当前数量:%d\n", dataSource->product_quantity);
		// 购买商品
		dataSource->product_quantity--;
		Common::printlog(LOG_LEV_ERROR, "购买1个\n");
		dataSource->C_Sum++;
		dataSource->m_renderEngine->getPropertySystem()->setPropertyValue(ssrObject, "ConsumerSum", Common::int2str(dataSource->C_Sum));
		dataSource->m_renderEngine->getPropertySystem()->setPropertyValue(ssrObject, "BufferSize", Common::int2str(dataSource->product_quantity));
		dataSource->m_renderEngine->getPropertySystem()->setPropertyValue(ssrObject, "Text", "购买1个");
		pthread_mutex_unlock(&dataSource->mutex);// 解锁
		pthread_cond_signal(&dataSource->producer_cond);// 发送信号,唤醒等待的线程
		Sleep(2500);

	}

	return ssrObject;
}

编译

此时我们编译完成,鼠标右键弹出菜单,点击生成,找到我们生成后的文件路径

在这里插入图片描述

使用Plugin

1.打开ssRenderEditor,Resource窗口中点击New Plugin,选择刚才生成后的Plugin路径。
2.拖拽Plugin到Page节点下
3.创建4个Text节点设置Text属性绑定,用于显示Plugin的属性。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

小结:

制作工程时用时比较长的是理解线程的实现和一些接口的使用方法,需要注意的是使用pthread_cond_wait时最好用while循环判断,因为如果用if会出现虚假唤醒的情况:当信号中断时也会去唤醒它。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值