Thread factory of the nine Yin scriptures of C + +

The previous article ended the implementation of thread factory class, which mainly introduces the use of thread factory class.

Thread interface classes are divided into task model and data model. The process between them is the same, but the data storage is different.

Task model thread interface

template<typename RET, typename... Args>
class BaseTaskThread 

The function is passed in by the task model, RET is the return value of the function, Args is the parameter list type of the function, and the parameter type obtained through GetJob is:

std::shared_ptr<std::packaged_task<RET(Args ...)>>

Data model thread interface

template<typename RET, typename... Args>
class BaseDataThread

The data model passes in data, RET is the expected return data type, which is set by the user in the online process class, Args is the parameter list, and the parameter type obtained through GetJob is

std::shared_ptr<DataNode<std::tuple<Args ...>, RET>>

Example 1. General test of task model

class MyJob : public BaseTaskThread<bool, int>
{
public:
	MyJob(CThreadFactoryBase& factory, int start) :BaseTaskThread(factory), m_idx(start) {}
	void Run()override
	{
		while (!IsStop())
		{
			ValuePtrType task;
			if (GetJob(task))
			{
				(*task)(m_idx++);
			}
		}

	}
	int m_idx = 0;
};

bool Func3(int i)
{
	std::cout << i * 100 << "-->" << "Test function" << std::endl;
	return true;
}

class PrintTest {
public:
	bool Func1(int i, const std::string& msg)
	{
		std::cout << i << "-->" << msg << std::endl;
		return true;
	}

	bool Func2(int i)
	{
		std::cout << i << "-->" << "Test member functions" << std::endl;
		return false;
	}
};

int main()
{
	CThreadFactory<MyJob> fact;
	fact.Start(2, 100);

	for (size_t i = 0; i < 100; i++)
	{
		fact.Push([](int idx) {std::cout << "test lambda expression:" << idx << std::endl; return true; });
	}

	// //Test function
	auto ret = fact.Push(Func3);
	std::cout << "Get results:" << ret.get() << std::endl;

	// //Pass in the local parameter and calculate with the thread passed in parameter
	std::string strVal = "Hello";
	int add = 1000;
	auto ret2 = fact.Push(
	[strVal,add](int idx) {

		std::cout << "test lambda expression:" << strVal << "-->" << idx << std::endl;
		return true;
	});
	std::cout << "Get result 2:" << ret2.get() << std::endl;

	PrintTest p;
	//Member function
	fact.Push(std::bind(&PrintTest::Func2, &p, std::placeholders::_1));
	//Member function
	fact.Push(std::bind(&PrintTest::Func1, &p, std::placeholders::_1, "Mixed parameters"));

	 std::this_thread::sleep_for(std::chrono::milliseconds(5000));
     return 0;
}

Example 2. Batch execution of sql

class BatchSql : public BaseDataThread<int, std::string>
{
public:
	BatchSql(CThreadFactoryBase& factory) :BaseDataThread(factory) {}
	void Run()override
	{
		while (!IsStop())
		{
			ValuePtrType task;
			if (GetJob(task, 1))
			{
				//std::string strSql = std::get<0>(task->data);
				m_vecSqlList.push_back(task);
			}
			else
			{
				for (auto& item : m_vecSqlList)
				{
					std::cout << "No data received for more than 1 second, execute script" << std::get<0>(item->data) << std::endl;
					item->res.set_value(1);
				}
				m_vecSqlList.clear();
			}
			if (m_vecSqlList.size() == 10)
			{
				for (auto& item : m_vecSqlList)
				{
					std::cout << "Batch script execution" << std::get<0>(item->data) << std::endl;
					item->res.set_value(1);
				}
				m_vecSqlList.clear();
			}
		}

	}
	std::vector<ValuePtrType> m_vecSqlList;
};

int main()
{
    CThreadFactory<BatchSql> sqlExec;
	sqlExec.Start(1);
	for (size_t i = 0; i < 100; i++)
	{
		std::stringstream ss;
		ss << "insert into tabName(id, name) value(";
		ss << i;
		ss << ",'Zhang San')";
		sqlExec.Push(ss.str());
	}
	 
	auto ft = sqlExec.Push("Test synchronous execution");
	std::cout << "results of enforcement" << ft.get() << std::endl;

	std::this_thread::sleep_for(std::chrono::milliseconds(5000));
    return 0;
}

Tags: Programming Lambda SQL

Posted on Wed, 03 Jun 2020 10:38:28 -0400 by dominant