Sign in to follow this  

help starting with threads

This topic is 3493 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

i have this code, and its a callback function for a Canon EOS Camera. When the camera sends a property change event, that is my que to start downloading live images from the camera. My first problem was that it would only download the first image then exit the function, so i put in an infinite loop with a Sleep method at the end of it. Now my problem is that i can never exit it, my application completely freezes. i have some friends tell me that i need to create a new thread for this process, the problem is i have never dealt with threads. How can i put this process onto a new thread? (note: this process starts when user clicks a button, and ends when the user closes the destinations output window) thanks in advance
EdsError EDSCALLBACK ScanGUI::PropertyEventHandler(EdsUInt32 inEvent, EdsUInt32 inProperty, EdsUInt32 inParam, EdsVoid* inContext)
{
	EdsError err = EDS_ERR_OK;
	EdsStreamRef stream = NULL;
	EdsEvfImageRef evfImage = NULL;
	EdsUInt32 bufferSize = 2 * 1024 * 1024;

	switch (inEvent)
	{
		//download and display evf data
		case kEdsPropertyEvent_PropertyChanged:
			while (cam_sdk->live_view_enabled())
			{
				EdsCameraRef cam = cam_sdk->get_current_cam();

				// Create memory stream.
				err = EdsCreateMemoryStream(bufferSize, &stream);

				// Create EvfImageRef.
				if (err == EDS_ERR_OK)
					err = EdsCreateEvfImageRef(stream, &evfImage);
	

				// Download live view image data.
				if (err == EDS_ERR_OK)
					err = EdsDownloadEvfImage(cam, evfImage);

				//get zoom/etc..
				if (err == EDS_ERR_OK)
				{
					unsigned char* pbyteImage = NULL;
					EdsUInt32	size;
					EdsUInt32	zoom;
					EdsPoint	zoomPos;
					EdsPoint	imagePos;
					EdsUInt32	histogram;

					EdsGetPropertyData(evfImage, kEdsPropID_Evf_Zoom, 0, sizeof(zoom), &zoom);
					EdsGetPropertyData(evfImage, kEdsPropID_Evf_ZoomPosition, 0, sizeof(zoomPos), &zoomPos);
					EdsGetPropertyData(evfImage, kEdsPropID_Evf_ImagePosition, 0, sizeof(imagePos), &imagePos);
					EdsGetPropertyData(evfImage, kEdsPropID_Evf_Histogram, 0, sizeof(histogram), &histogram);

					EdsSetPropertyData(cam, kEdsPropID_Evf_Zoom, 0, sizeof(zoom), &zoom);
					EdsSetPropertyData(cam, kEdsPropID_Evf_ZoomPosition, 0, sizeof(zoomPos), &zoomPos);
					EdsSetPropertyData(cam, kEdsPropID_Evf_ImagePosition, 0, sizeof(imagePos), &imagePos);
					EdsSetPropertyData(cam, kEdsPropID_Evf_Histogram, 0, sizeof(histogram), &histogram);

					EdsGetPointer(stream, (EdsVoid**)&pbyteImage);
					
					if (pbyteImage != NULL)
					{
						EdsGetLength(stream, &size);
						HDC dc = GetDC(evfWin->GetHWND());
						CImage image;
						CComPtr<IStream> strm2 = NULL;
						HGLOBAL hMem = ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, size);
						LPVOID pBuff = ::GlobalLock(hMem);
						memcpy(pBuff, pbyteImage, size);
						::GlobalUnlock(hMem);
						CreateStreamOnHGlobal(hMem, TRUE, &strm2);
						image.Load(strm2);
						CRect rect;
						GetWindowRect(evfWin->GetHWND(), &rect);

						//draw
						SetStretchBltMode(dc, COLORONCOLOR);
						image.StretchBlt(dc, 0, 0, rect.Width(), rect.Height(), 0, 0, image.GetWidth(), image.GetHeight(), SRCCOPY);
						image.Destroy();
						::GlobalFree(hMem);
						ReleaseDC(evfWin->GetHWND(), dc);
					}
				}

				if(stream != NULL)
				{
					EdsRelease(stream);
					stream = NULL;
				}
		
				if(evfImage != NULL)
				{
					EdsRelease(evfImage);
					evfImage = NULL;
				}

				Sleep(400);
			}
			break;

Share this post


Link to post
Share on other sites
I'm not sure if a thread would solve your problem. I mean you could put that function in a separate thread but then that thread would run in an infinite loop instead of your main thread.

IMO there must be a way for you to find out how many images there are waiting to be downloaded so you can leave the function once you've retrieved all the images you wanted.


Anyway if you still want to use a thread (even though I don't see how that would help), normally I'd suggest using boost.Thread ... however, you may not want to have to install boost just to start a thread, so if you'd rather do it using just the standard WIN32 API, look up the _beginthreadex() function. You basically pass it the address of a function that the thread is to execute.

That said, I don't recommend just jumping into threading without having had any experience with it, because once you start using threads there are tons of opportunities to shoot yourself in the foot if you don't know what you're doing.

Share this post


Link to post
Share on other sites
thank you very much. there is no certain number of images to download, its live view from a camera so i could download images all day if needed. also is there a way i can kill a thread process after ive started one? my plan was to start this thread in an loop and exit the loop and thread once the live view window is closed.

im very new to threads, is there a way i can store a pointer to a thread and then use that pointer later on to kill it?'

thank you again

Share this post


Link to post
Share on other sites
I think there is a way to kill a running thread, but that that's not the proper way to do it. The proper way is to send your thread a message (either using PostThreadMessage() or by setting a flag that the thread must check periodically).


// pseudo code

// in your thread ...
unsigned int threadFunc( void* pUserData )
{
while ( bContinueRunning )
{
// do some work ...
}

// leave the function (exit from thread)
}

// in your main thread ... cause our worker thread to end
bContinueRunning = false



Beware that you need to synchronize access to your bContinueRunning flag somehow. Normally this involves the functions EnterCriticalSection() and LeaveCriticalSection(), but I've learned that in the case of simple booleans, just making the bool volatile is enough.

If you decide to use PostThreadMessage() instead (which I'd recommend) then your worker thread has to use PeekMessage() in a loop to check if it has been sent a message telling it to terminate.

Share this post


Link to post
Share on other sites
Well then you need to tell your friends they don't know what they are talking about. It is possible to write your app single threaded if you want. In your app all you need to do is process a single frame go do other stuff then come back to the camera for the next frame.

Share this post


Link to post
Share on other sites

This topic is 3493 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this