high cpu load with wxThreads

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
totobond
Earned a small fee
Earned a small fee
Posts: 11
Joined: Mon Oct 02, 2006 10:01 am

high cpu load with wxThreads

Post by totobond »

Hi

I have several threads (from 1 to 100) that are doing some computations (looking for an opened port) and updates GUI frame (through postEvent() method) once a port is found.

My problem is that CPU load is really too high (around 99%) (if I have 1 or 100 threads , that's the same !!!)
I set threads priorities to 0 (low) but nothing changes....

Am I missing something in terms of thread initialization, or else ???

Any idea would be very appreciate !!

Regards

Antonio
protocol
Moderator
Moderator
Posts: 680
Joined: Wed Jan 18, 2006 6:13 pm
Location: Dallas, TX
Contact:

Post by protocol »

It may not be the threads (I totally doubt threads alone will create any additional CPU load), but it probably is caused by your socket logic. How are you waiting/listening for ports? Are you using wxSocket? What OS are you running?

If using wxSocket it may be best if you use the blocking socket flags, since I assume they will be on a detached thread. And check out: http://forums.wxwidgets.org/viewtopic.php?p=11349

If you need further help/examples let me know.

best regards.
/* UIKit && wxWidgets 2.8 && Cocoa && .Net */
QuRegExmm
wxPCRE & ObjPCRE - Regex It!
upCASE
Moderator
Moderator
Posts: 3176
Joined: Mon Aug 30, 2004 6:55 am
Location: Germany, Cologne

Post by upCASE »

Hi!
I guess this might just be normal behavior. Using threads doesn't mean that the CPU level will be low, but that some actions can be carried out in "parallel" ways.

It depends on what you do in the thread. If you do some kind of busy waiting for example, it will definitely raise the CPU usage.

How do you scan for these ports?
What OS are you on?
Can we see some code?

It's hard to tell how to improve the usage without having anything "concrete". Just keep in mind: Using threads has absolutely nothing to do with "better performance".
OS: OpenSuSE, Ubuntu, Win XP Pro
wx: svn
Compiler: gcc 4.5.1, VC 2008, eVC 4

"If it was hard to write it should be hard to read..." - the unknown coder
"Try not! Do. Or do not. There is no try." - Yoda
totobond
Earned a small fee
Earned a small fee
Posts: 11
Joined: Mon Oct 02, 2006 10:01 am

Post by totobond »

Hi Here is my brief code

Code: Select all

void* MyThread::Entry ()
{
        unsigned short portidx=0;

	for (portidx = 0; portidx <= 65535; portidx++)
	{
		if (TestDestroy()) break;
		SOCKADDR_IN dest_id; 

		socket_id = socket(AF_INET, SOCK_STREAM, 0);
		if (socket_id == INVALID_SOCKET) return NULL;

		dest_id.sin_family      = AF_INET;
		dest_id.sin_addr.s_addr = inet_addr("127.0.0.1"); 
		dest_id.sin_port        = htons(portidx); 

		int res = bind(socket_id, (struct sockaddr*)&dest_id,                sizeof(dest_id));
		if (res != 0) 
		{
			   wxCommandEvent evt(wxMY_EVENT);
			   evt.SetClientData((void *)&portidx);
                           ::wxPostEvent(m_parent, evt);
                } 
	}
}
My custom event method on wxFrame

Code: Select all

void MyFrame::OnProcessMyEvent(wxCommandEvent & evt)
{
	unsigned short * port = (unsigned short *) evt.GetClientData();
	wxString myport = myport.Format("%i", *port);
		int nb = list->GetItemCount();
		list->InsertItem(nb+1, "");
		list->SetItem(nb, 0, myport);
 }
So I find strange that this small code takes too much CPU resources.
I agree that if treatment was too complex in my thread, my CPU will be impacted but here it is only socket() and bind() functions.

Perhaps if I directly use raw sockets or wxSocket I will improve something

My environment

I'm under win XP, wxwidget 2.8.0 and .NET2005
upCASE
Moderator
Moderator
Posts: 3176
Joined: Mon Aug 30, 2004 6:55 am
Location: Germany, Cologne

Post by upCASE »

Hi!
First of all I noticed that you check the whole range of ports in each of the threads started. Is this a desired action?

Maybe try using AddPendingEvent() directly. Use ::wxMutexGuiEnter() and ::wxMutexGuiLeave.

Another option would be to let go of the threads and code some small platform specific code. On Windows you can use GetTCPTable and GetUDPTable to get a list of ports in use. So, having the ports in use means, all others not used are free :)
Can't think of a proper way to do this in unix, but maybe something similar to "cat /proc/net/tcp" could help...

I suppose the real problem here might be that you update the list every time. Maybe it would be a better option to have a list of some kind, store the ports there and then add the whole list in one step. Freeze() the GUI before that and Thaw() it afterwards.
OS: OpenSuSE, Ubuntu, Win XP Pro
wx: svn
Compiler: gcc 4.5.1, VC 2008, eVC 4

"If it was hard to write it should be hard to read..." - the unknown coder
"Try not! Do. Or do not. There is no try." - Yoda
totobond
Earned a small fee
Earned a small fee
Posts: 11
Joined: Mon Oct 02, 2006 10:01 am

Post by totobond »

Hi

Thanks for the ideas. I'm going to try and will let you know .. if something was improved

Thanks

Antonio
PhoenixPl
I live to help wx-kind
I live to help wx-kind
Posts: 179
Joined: Wed Feb 15, 2006 9:26 am

Post by PhoenixPl »

If this is not the only thing that you are doing in threads and some of your operations are long term computation then you should also think about adding ether wxThread::Sleep(...) or wxThread::Yield().
wxThread::Yield
void Yield()

Give the rest of the thread time slice to the system allowing the other threads to run. See also Sleep().
Post Reply