Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ MT-multithreading and servers » How to use CoWork and Progress together?
How to use CoWork and Progress together? [message #53511] Tue, 07 April 2020 14:58 Go to next message
Tom1
Messages: 818
Registered: March 2007
Experienced Contributor
Hi,

I've been trying to make CoWork and Progress work nicely together, but I just can't figure out what have I done wrong:

	Progress pg;
	pg.Title("A parallel processing job");
	pg.SetText("Working on many items at once...");
	pg.Set(0, 100);
	
	Atomic done=0;

	CoWork co;

	co * [&] {
		for(int i = co.Next(); i < 100 ; i = co.Next()) {
			Sleep(100); // Doing something...
			
			// OK, now it is done, update progress:
			
			GuiLock _;
			pg.SetPos(AtomicInc(done));
		}
	};
	
	co.Finish();


Any suggestions how to make it work as it should? Now it just freezes at or near the end...

Best regards,

Tom
Re: How to use CoWork and Progress together? [message #53514 is a reply to message #53511] Tue, 07 April 2020 16:39 Go to previous messageGo to next message
Tom1
Messages: 818
Registered: March 2007
Experienced Contributor
Hi,

I finally found the solution:

	Progress pg;
	pg.Title("A parallel processing job");
	pg.SetText("Working on many items at once...");
	pg.Set(0, 100);

	Atomic done=0;
	Atomic stop=0;

	CoWork co;
	for(int t=0;t<co.GetPoolSize();t++){
		co & [&] {
			for(int i = AtomicInc(done); i<100;i = AtomicInc(done)){
				Sleep(1000); // Doing something...
				if(stop) break;
			}
		};
	}
	
	while(!co.IsFinished()){
		if(pg.Canceled()){
			AtomicInc(stop);
			break;
		}
		pg.SetPos(done);
		Sleep(100);
	}
	co.Finish();


So, in the end I did have to give up the CoWork::Loop (operator *) and do approximately the same externally to avoid internal co.Finish(); Now the GUI is accessed entirely in the main thread and there are no more issues.

Best regards,

Tom
Re: How to use CoWork and Progress together? [message #53538 is a reply to message #53511] Thu, 09 April 2020 10:41 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13050
Registered: November 2005
Ultimate Member
Well, it obviously breaks rules here:

void Progress::Process()
{
	if(!IsOpen()) {
		dword t = msecs();
		if((int)(t - show_time) >= show_delay) {
			Create(); // !!! no top-level window manipulation in non-main thread
			show_time = t;
		}
	}
	if(IsOpen()) {
		GuiSleep(0); // no message processing in non-main thread
		ProcessEvents();
	}
}
Re: How to use CoWork and Progress together? [message #53539 is a reply to message #53538] Thu, 09 April 2020 13:13 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13050
Registered: November 2005
Ultimate Member
This works:

GUI_APP_MAIN
{
	Progress pg;
	pg.Title("A parallel processing job");
	pg.SetText("Working on many items at once...");
	pg.Set(0, 100);
	
	std::atomic<int> ii(0);
	CoDo([&] {
		for(int i = ii++; i < 100 ; i = ii++) {
			Sleep(1000); // Doing something...
			
			// OK, now it is done, update progress:
			
			if(IsMainThread())
				pg.SetPos(ii);
		}
	});
}


(CoDo is "new and shiny" variant of CoWork::*)

I will try to make this into the CtrlLib.

Mirek
Re: How to use CoWork and Progress together? [message #53540 is a reply to message #53539] Thu, 09 April 2020 14:01 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13050
Registered: November 2005
Ultimate Member
So now some Progress methods can be called without restriction in MT.

This is a new reference example:

#include <CtrlLib/CtrlLib.h>

using namespace Upp;

GUI_APP_MAIN
{
	Progress pi("Working on many items at once...", 100);
	std::atomic<int> ii(0);
	CoDo([&] {
		for(int i = ii++; i < 100; i = ii++) {
			for(int q = 0; q < 1000; q++) {
				if(pi.Canceled()) // ideally call Canceled every 1-10ms
					return;
				Sleep(1); // work simulation
			}
			pi.Step();
		}
	});
}
Re: How to use CoWork and Progress together? [message #53554 is a reply to message #53540] Sat, 11 April 2020 11:14 Go to previous messageGo to next message
Tom1
Messages: 818
Registered: March 2007
Experienced Contributor
Hi Mirek,

This is a nice and stylish improvement!

However, there is still something to fix as using this through a menu leaves the app frozen at or near the completion of parallel processing. Here's a testcase based on the reference example:

#include <CtrlLib/CtrlLib.h>

using namespace Upp;

class Test: public TopWindow{
public:
	typedef Test CLASSNAME;
	MenuBar menu;
	
	void Worker(){
		Progress pi("Working on many items at once...", 100);
		std::atomic<int> ii(0);
		CoDo([&] {
			for(int i = ii++; i < 100; i = ii++) {
				for(int q = 0; q < 1000; q++) {
					if(pi.Canceled()) // ideally call Canceled every 1-10ms
						return;
					Sleep(1); // work simulation
				}
				pi.Step();
			}
		});
	}
	
	void MainMenu(Bar &bar){
		bar.Add("Process...", THISFN(Worker));
	}
	
	Test(){
		AddFrame(menu);
		menu.Set([=](Bar& bar) { MainMenu(bar); });
	}
};

GUI_APP_MAIN
{
	Test test;
	test.Run();
}


Thanks and best regards,

Tom
Re: How to use CoWork and Progress together? [message #53559 is a reply to message #53554] Sat, 11 April 2020 23:10 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13050
Registered: November 2005
Ultimate Member
Nice deadlock Smile

Hopefully fixed.

Mirek
Re: How to use CoWork and Progress together? [message #53565 is a reply to message #53559] Mon, 13 April 2020 09:52 Go to previous messageGo to next message
Tom1
Messages: 818
Registered: March 2007
Experienced Contributor
Hi Mirek,

Thanks! It works now correctly. Smile

Best regards,

Tom
Re: How to use CoWork and Progress together? [message #53568 is a reply to message #53565] Mon, 13 April 2020 12:41 Go to previous messageGo to next message
deep is currently offline  deep
Messages: 227
Registered: July 2011
Location: Bangalore
Experienced Member
Hi

I checked this on my system.
I am using Lubuntu 16.04, gtk3 clang

I get following error

index.php?t=getfile&id=6042&private=0


Warm Regards

Deepak
Re: How to use CoWork and Progress together? [message #53573 is a reply to message #53568] Mon, 13 April 2020 13:26 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 13050
Registered: November 2005
Ultimate Member
deep wrote on Mon, 13 April 2020 12:41
Hi

I checked this on my system.
I am using Lubuntu 16.04, gtk3 clang

I get following error

index.php?t=getfile&id=6042&private=0


I have been trying for about 5 minutes, all seems to be OK.

Are you testing with current trunk?

Mirek
Re: How to use CoWork and Progress together? [message #53577 is a reply to message #53573] Mon, 13 April 2020 14:05 Go to previous message
deep is currently offline  deep
Messages: 227
Registered: July 2011
Location: Bangalore
Experienced Member
Hi

I was on 14219

Now with Latest 14297 it is working fine.

Thanks Mirek.


Warm Regards

Deepak
Previous Topic: [NOT REPRODUCIBLE] HttpRequest gzip format error
Next Topic: ASyncWork/CoWork Cancel() method leads to deadlock (when used with GuiLock)
Goto Forum:
  


Current Time: Fri Jan 22 17:39:46 CET 2021

Total time taken to generate the page: 0.01053 seconds