Click here to Skip to main content
15,881,812 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi, i like to have my threads to be in the sleep state as long there is nothing to do for it. It should then weak up via condition variable waiting on a queue entry but also on several other conditions or events made by user interrupts or by external mqtt libary callback function or even a timer. I can weak them by using those WaitFor...Object, but do not like to use those Winapis. I am just curious if there is a well established concept achieving that.

What I have tried:

C++
int MQTT_Thread(void)
{
	BOOL loop;
	HANDLE wakeup;

	//if (!QueueUserAPC((PAPCFUNC)Wake_On_Events, GetCurrentThread(), 0))
	{
		//std::cout << "QueueUserAPC eror " << GetLastError() << std::endl;
	}

	try {
		// Create a client mqtt
		mqtt::client cli(SERVER_ADDRESS, CLIENT_ID);

		mqtt::connect_options connOpts;
		connOpts.set_keep_alive_interval(20);
		connOpts.set_clean_session(true);

		wakeup = CreateEvent(NULL, false, false, NULL);
		if (wakeup == NULL)
			throw MainException("CreateEvent failed in thread.");

		events[0] = wakeup;
		events[1] = SystemTimerEvent;

		callback cb(wakeup);

		// Set the callback function defined in custom class callback
		cli.set_callback(cb);

		// Connect to the client
		cli.connect(connOpts);

		// Subscribe for topic all
		cli.subscribe("test", 1);

		// Publish using a message pointer.
		auto msg = mqtt::make_message(TOPIC, PAYLOAD1);
		msg->set_qos(QOS);

		cli.publish(msg);
		// Now try with itemized publish.
		cli.publish(TOPIC, PAYLOAD2, strlen(PAYLOAD2), 0, false);

		loop = true;
		//while (loop)
		{
			//DWORD ret = WaitForSingleObjectEx(wakeup, INFINITE, true);
			//DWORD ret = WaitForMultipleObjects(2,events,false,INFINITE);
			//std::cout << "Waked due event" << ret << std::endl;
			//SleepEx(INFINITE,true);
			//std::cout << "Waked due event from APC" << std::endl;
		}
		// Disconnect
		cli.disconnect();
	}
	catch (const mqtt::exception& exc) {
		std::cerr << "Error: " << exc.what() << " [" << exc.get_reason_code() << "]" << std::endl;
		return 1;
	}
	catch (const MainException& e) {
		std::cout << e.what() << std::endl;
	}

	return 0;
}
Posted
Updated 30-Dec-21 7:07am
v2
Comments
Richard MacCutchan 28-Dec-21 11:45am    
"if there is a well established concept achieving that."
Yes, the Win APIs, specially designed to make your application run correctly.

1 solution

Thanks for fast answering.
No i meant just using the a condition variable like

cv.wait(lk, [this] { return !q.empty(); });

there must be a way by expanding the return condition and specifiy it with your own events.
I think the cv.wait() function will keep the thread asleep aslong the q.empty() function return value remains true. So there must be some kind of background check. One idea of mine is to possibly add some more atomic boolean and change them by my own back ground thread receiving all the events i am interested in and change all bool variable consequently. But this needs to implement a additional thread for that silly thing i thought there is something allready been done in c++ libary or winapi for that purpose.
 
Share this answer
 
Comments
Rick York 28-Dec-21 12:59pm    
This should have been a reply to Richard's comment which is accurate. WaitForMultipleObjects is probably the one that should be used. It takes an array of objects than can hold 64 items in a 64-bit Windows OS. This really does work and it works quite well. I implemented a subscription service for a thread pool using this mechanism and it works great. Windows supports a variety of signal-able events that you can wait on. If you use named objects they can even be controlled by different processes which is what I do.
KarstenK 30-Dec-21 13:09pm    
Plz write it as answer to close the Q&A.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900