threading issues

Feb 14, 2012 at 7:28pm
as a reply on my previous thread indicated that learning threading should be easier than what I was doing, I'm looking into it. After spending 6 hours on it, I'm still more or less nowhere in regards to what I want to do.

as a basic example of what I want to use the threading for, let's assume that I have a vector with 1,000 strings containing pathnames to .jpg files. I want to run jpegoptim on each of them, BUT I only want 8 processes to run concurrently (as I have a quad-core i7, with hyperthreading, and even on processors with less logical cores, 8 is a low enough number to avoid the inevitable crashes that launching 1,000 concurrent instances of jpegoptim would cause).

I have been able to figure out how to create a thread, however the only two ways that I have been able to work out to get it to do what I want are encountering issues.

Method 1: create a group using thread_group, use get_id to check for finished threads in a loop, delete the finished thread, and add a new one.

Problems: first of all, the simple code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <string>
#include <boost/thread.hpp>
using namespace std;
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

int main(void){
	boost::thread_group threads;

cout << "Press Enter to Continue";
cin.ignore(999,'\n');
    return 0;
}


compiles, but upon debug, throws an error of:
"Debug Assertion Failed!

Program: ~~~
File:c:\program files (x86)\microsoft visual studio 10.0\vc\include\list
Line: 286

Expression: list iterators incompatible
~~~"

when debugging, it shows the error as being in stdthrow.cpp. the same error occurs if I specifically call the destructor via threads.~thread_group();. please note that the program works until the destructor is called (either manually or at the end of the program).

Method 2:
manually run 8 threads, and when one finishes (again, checked via get_id), delete it and start a new one.

Problem: either the thread destructor doesn't appear to work properly, or (more likely) I'm Doing It Wrong.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <string>
#include <boost/thread.hpp>
using namespace std;
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

void worker(unsigned int disp){
	cout << disp << endl;
}

int main(void){
	boost::thread one(worker,1);
	boost::thread two(worker,2);
	boost::thread three(worker,3);
	boost::thread four(worker,4);
	boost::thread five(worker,5);
	boost::thread six(worker,6);
	boost::thread seven(worker,7);
	boost::thread eight(worker,8);
	one.join();
	one.~thread();
	__if_exists(one){cout << "one exists" << endl;}
	__if_not_exists(one){cout << "one does not exist" << endl;}
cout << "Press Enter to Continue";
cin.ignore(999,'\n');
    return 0;
}


this always returns "one exists", preventing me from using this code in a loop (as the compiler will rule it a redeclaration of an existing variable).

Any help would be greatly appreciated; it's pretty frustrating that I can't find the error code from destroying the thread_group, and that almost everything I look up regarding threading deals with mutexes, locking, and race conditions -- none of which matter in such a simple case as mine. All I want to do is be able to run 8 concurrent processes at a time!

as I noted in my other thread, please keep in mind that I am *not* a programming student or professional programmer -- pretty much everything I know is self-taught and as such, my code doesn't follow any sort of standards and complicated stuff will likely go over my head. I don't use c++ (or any other single programming/scripting language) enough to warrant spending a few months going thru a "proper" programming book to learn it properly.
Last edited on Feb 14, 2012 at 7:30pm
Feb 14, 2012 at 7:53pm
See my post in your other thread.
Feb 14, 2012 at 7:55pm
I don't think you understand what __if_exists does. You created one on line 14 so of course it exists.

one.~thread();
Don't do this. The destructor of one will be called when the function ends. If it's called twice things might go wrong.
Feb 14, 2012 at 8:19pm
peter: you're probably right -- I assumed that if i called the destructor, it would destroy the variable, which would then cause __if_exists to return false (and therefore not run). as for calling the destructor, the idea is that I need to call the destructor in the function once the thread finishes, so that I can recreate it to run again (remember, there are 1,000 files to process). it's entirely possible that I'm going about this the wrong way, but that's why I posted ;P
Feb 14, 2012 at 8:44pm
Eric see your other post as well for an example class using boost::thread. You can copy and paste this code to get you started.

http://www.cplusplus.com/forum/general/61851/
Last edited on Feb 14, 2012 at 8:45pm
Feb 14, 2012 at 10:45pm
finally got it sorted, thanks to clanmjc's help. solution at bottom of thread linked above.
Topic archived. No new replies allowed.