Signaling main thread to finish the program when any child pthread meets conditional
up vote
-1
down vote
favorite
My attempt to describe the problem:
I am trying to create all possible permutations of a certain length from a set of 6 characters - for example {A,B,C,D,E,F} - and hash each permutation using an MD5 cryptography function which hashes my original permutation into a string of 32 characters and stores it in a vector. I want to have 6 vectors of hashes where each vector is for permutations of lengths 1 through 6 (Example: vector1 stores hashes of permutations of length 1, vector2 for length 2, etc.)
So I have a function that recursively creates the permutations of a certain length from the set of characters, MD5 hashes each permutation, then stores each into a vector. Here is the function:
void MD5Hashes(vector<string>& vec, const char str, string prefix, const int n, const int length){
if(length == 1){
for(int j = 0; j < n; j++){
vec.push_back(md5(prefix + str[j])); // MD5 hash and push_back
}
}
else{
for(int i = 0; i < n; i++){
MD5Hashes(vec, str, prefix + str[i], n, length - 1);
}
}
}
So now what I'm aiming for is to create 6 pthreads from main, where each pthread uses the function above to create the permutations of appropriate length (Example: thread1 creates permutations of length 1 then hashes and stores into a vector, thread2 does length2, etc.) however the whole point to this is that I have my own chosen string let's say "ABC" and its MD5 hash which is a string of 32 characters - and I want to see if my hash matches any of the ones created by my pthreads. So in this case since my string is "ABC" of length 3, thread 3 is in charge of creating this permutation "ABC" from the set of characters so their should be a match within the hashes that this thread created.
My actual problem:
I want to be able to find a matching hash while creating the permutations and its hash in each pthread - and somehow signal that a match has been found to main indicating that a match has been found. Then main should kill all child pthreads since the match has been found and there is no need to continue creating permutations and their hashes. The following is my implementation without trying to signal:
#include <iostream>
#include <pthread.h>
#include <cstdlib>
#include <string>
#include <vector>
#include <algorithm>
#include <time.h>
#include "md5.h"
using namespace std;
#define NUM_THREADS 6 // Number of pthreads
#define SIZE_ASCII 6 // sizeof str below, set of characters to create permutations from
char str = {'A','B','C','D','E','F'};
// Struct object mainly used to store the permutations of lengths 1-6
struct HashStruct{
vector<string> hashes; // Stores MD5 hashes for permutations of certain length
string prefix; // Permutation
int length; // Length of each pre-hashed permutation
int identifier;
} perms_one, perms_two, perms_three, perms_four, perms_five, perms_six; // Six structs, one for each length of pre-hashed permutations
// Vector of HashStructs
vector<HashStruct>perms;
// Produce MD5 hashes from permutations of certain length from characters
// Then searches for matching MD5 hash
void MD5Hashes(vector<string>&, const char*, string, const int, const int);
// pthread function call for MD5Hashes
void *MD5Hashes(void*);
// Pre-hashed password
string password = "BCEF";
// MD5 hashed password - we are looking to match this in each pthread
string password_hash = md5(password);
int main(){
// Initializing vector of HashStruct elements - each struct element in vector used for MD5 hashing of permutations, then matching
perms.push_back(perms_one); perms.push_back(perms_two); perms.push_back(perms_three); perms.push_back(perms_four);
perms.push_back(perms_five); perms.push_back(perms_six);
for(int i = 0; i < perms.size(); i++){
perms[i].prefix = "";
perms[i].length = i + 1;
perms[i].identifier = i + 1;
}
// Timing program run time
clock_t t1, t2;
t1 = clock();
// Spawning pthreads - one for ineach set of permutations of lengths 1 through 8
pthread_t threads[NUM_THREADS];
int id[NUM_THREADS];
for(int i = 0; i < NUM_THREADS; i++){
id[i] = i;
pthread_create(&threads[i], NULL, MD5Hashes, &id[i]);
}
for(int i = 0; i < NUM_THREADS; i++){
pthread_join(threads[i], NULL);
}
// End run time
t2 = clock();
cout << "nTime elapsed: " << (t2-t1)/(double)CLOCKS_PER_SEC << endl << endl;
return 0;
}
// Method produces sizeof(str) ^ length permutations, where length is length number of characters from pre-hashed permutation
void MD5Hashes(vector<string>& vec, const char str, string prefix, const int n, const int length){
if(length == 1){
for(int j = 0; j < n; j++){
vec.push_back(md5(prefix + str[j])); // MD5 hash and push_back
}
}
else{
for(int i = 0; i < n; i++){
MD5Hashes(vec, str, prefix + str[i], n, length - 1);
}
}
}
// pthread MD5Hashes call method: first produces hashes then searches for match
void* MD5Hashes(void* arg){
int* int_arg = (int*) arg; // get the int argument which will be used as index to access HashStruct from perms[i]
int index = *int_arg;
struct HashStruct* perm = (struct HashStruct*)&perms[index];
MD5Hashes(perm->hashes, str, perm->prefix, SIZE_ASCII, perm->length);
// Search for matching hash
if(std::find(perm->hashes.begin(), perm->hashes.end(), password_hash) != perm->hashes.end()){
cout << "MATCHING HASH FOUND" << endl;
cout << "Found in thread of lengths: " << perm->identifier << endl;
cout << "MD5 Hash: " << password_hash << endl;
cout << "Password: " << password << endl;
pthread_exit(NULL);
}
pthread_exit(NULL);
}
Exploring signaling to main using conditional variable and mutex:
The following is a snippet of code from an unrelated attempt to the problem above. The point is that I am creating 100 pthreads and want to stop when the 15th thread is executing and signal main to finish the program. I believe that if I grasp the concept of signaling and condition waiting from main, then I can adapt this to my actual problem. If anybody can please help guide me and tell me where my logic is flawed, it would be greatly appreciated. Because currently my implementation when using a full set of alphanumeric characters and taking lengths 1-8 is crashing
#include <iostream>
#include <pthread.h>
#include <cstdlib>
#include <string>
#include <vector>
#include <algorithm>
#include <time.h>
using namespace std;
#define NUM_THREADS 100
void* testFunc(void*);
pthread_cond_t cond;
pthread_mutex_t mutex;
bool found_match;
int main(){
// Tracking execution time
clock_t t1, t2;
t1 = clock();
// Condition variable signaled from other thread
// Mutex to exclusively update bool
pthread_cond_init(&cond, NULL);
pthread_mutex_init(&mutex, NULL);
found_match = false;
// Spawn NUM_THREADS pthreads
pthread_t threads[NUM_THREADS];
int id[NUM_THREADS];
for(int i = 0; i < NUM_THREADS; i++){
id[i] = i;
pthread_create(&threads[i], NULL, testFunc, &id[i]);
}
pthread_mutex_lock(&mutex);
while(!found_match){
pthread_cond_wait(&cond, &mutex);
}
pthread_mutex_unlock(&mutex);
// Cleaning up condition variable and mutex
pthread_cond_destroy(&cond);
pthread_mutex_destroy(&mutex);
cout << "Hello from main thread!" << endl;
t2 = clock();
cout << "Time elapsed: " << (t2 - t1)/(double)CLOCKS_PER_SEC << endl;
return 0;
}
void* testFunc(void* arg){
int* int_arg = (int*) arg;
int id = *int_arg + 1;
if(found_match){
pthread_exit(NULL);
}
else if((found_match == false) && (id == 15)){
pthread_mutex_lock(&mutex);
cout << "Hello from Thread ID: " << id << endl;
found_match = true;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
cout << "Hello from Thread ID: " << id << endl;
pthread_exit(NULL);
}
c++ multithreading recursion pthreads
add a comment |
up vote
-1
down vote
favorite
My attempt to describe the problem:
I am trying to create all possible permutations of a certain length from a set of 6 characters - for example {A,B,C,D,E,F} - and hash each permutation using an MD5 cryptography function which hashes my original permutation into a string of 32 characters and stores it in a vector. I want to have 6 vectors of hashes where each vector is for permutations of lengths 1 through 6 (Example: vector1 stores hashes of permutations of length 1, vector2 for length 2, etc.)
So I have a function that recursively creates the permutations of a certain length from the set of characters, MD5 hashes each permutation, then stores each into a vector. Here is the function:
void MD5Hashes(vector<string>& vec, const char str, string prefix, const int n, const int length){
if(length == 1){
for(int j = 0; j < n; j++){
vec.push_back(md5(prefix + str[j])); // MD5 hash and push_back
}
}
else{
for(int i = 0; i < n; i++){
MD5Hashes(vec, str, prefix + str[i], n, length - 1);
}
}
}
So now what I'm aiming for is to create 6 pthreads from main, where each pthread uses the function above to create the permutations of appropriate length (Example: thread1 creates permutations of length 1 then hashes and stores into a vector, thread2 does length2, etc.) however the whole point to this is that I have my own chosen string let's say "ABC" and its MD5 hash which is a string of 32 characters - and I want to see if my hash matches any of the ones created by my pthreads. So in this case since my string is "ABC" of length 3, thread 3 is in charge of creating this permutation "ABC" from the set of characters so their should be a match within the hashes that this thread created.
My actual problem:
I want to be able to find a matching hash while creating the permutations and its hash in each pthread - and somehow signal that a match has been found to main indicating that a match has been found. Then main should kill all child pthreads since the match has been found and there is no need to continue creating permutations and their hashes. The following is my implementation without trying to signal:
#include <iostream>
#include <pthread.h>
#include <cstdlib>
#include <string>
#include <vector>
#include <algorithm>
#include <time.h>
#include "md5.h"
using namespace std;
#define NUM_THREADS 6 // Number of pthreads
#define SIZE_ASCII 6 // sizeof str below, set of characters to create permutations from
char str = {'A','B','C','D','E','F'};
// Struct object mainly used to store the permutations of lengths 1-6
struct HashStruct{
vector<string> hashes; // Stores MD5 hashes for permutations of certain length
string prefix; // Permutation
int length; // Length of each pre-hashed permutation
int identifier;
} perms_one, perms_two, perms_three, perms_four, perms_five, perms_six; // Six structs, one for each length of pre-hashed permutations
// Vector of HashStructs
vector<HashStruct>perms;
// Produce MD5 hashes from permutations of certain length from characters
// Then searches for matching MD5 hash
void MD5Hashes(vector<string>&, const char*, string, const int, const int);
// pthread function call for MD5Hashes
void *MD5Hashes(void*);
// Pre-hashed password
string password = "BCEF";
// MD5 hashed password - we are looking to match this in each pthread
string password_hash = md5(password);
int main(){
// Initializing vector of HashStruct elements - each struct element in vector used for MD5 hashing of permutations, then matching
perms.push_back(perms_one); perms.push_back(perms_two); perms.push_back(perms_three); perms.push_back(perms_four);
perms.push_back(perms_five); perms.push_back(perms_six);
for(int i = 0; i < perms.size(); i++){
perms[i].prefix = "";
perms[i].length = i + 1;
perms[i].identifier = i + 1;
}
// Timing program run time
clock_t t1, t2;
t1 = clock();
// Spawning pthreads - one for ineach set of permutations of lengths 1 through 8
pthread_t threads[NUM_THREADS];
int id[NUM_THREADS];
for(int i = 0; i < NUM_THREADS; i++){
id[i] = i;
pthread_create(&threads[i], NULL, MD5Hashes, &id[i]);
}
for(int i = 0; i < NUM_THREADS; i++){
pthread_join(threads[i], NULL);
}
// End run time
t2 = clock();
cout << "nTime elapsed: " << (t2-t1)/(double)CLOCKS_PER_SEC << endl << endl;
return 0;
}
// Method produces sizeof(str) ^ length permutations, where length is length number of characters from pre-hashed permutation
void MD5Hashes(vector<string>& vec, const char str, string prefix, const int n, const int length){
if(length == 1){
for(int j = 0; j < n; j++){
vec.push_back(md5(prefix + str[j])); // MD5 hash and push_back
}
}
else{
for(int i = 0; i < n; i++){
MD5Hashes(vec, str, prefix + str[i], n, length - 1);
}
}
}
// pthread MD5Hashes call method: first produces hashes then searches for match
void* MD5Hashes(void* arg){
int* int_arg = (int*) arg; // get the int argument which will be used as index to access HashStruct from perms[i]
int index = *int_arg;
struct HashStruct* perm = (struct HashStruct*)&perms[index];
MD5Hashes(perm->hashes, str, perm->prefix, SIZE_ASCII, perm->length);
// Search for matching hash
if(std::find(perm->hashes.begin(), perm->hashes.end(), password_hash) != perm->hashes.end()){
cout << "MATCHING HASH FOUND" << endl;
cout << "Found in thread of lengths: " << perm->identifier << endl;
cout << "MD5 Hash: " << password_hash << endl;
cout << "Password: " << password << endl;
pthread_exit(NULL);
}
pthread_exit(NULL);
}
Exploring signaling to main using conditional variable and mutex:
The following is a snippet of code from an unrelated attempt to the problem above. The point is that I am creating 100 pthreads and want to stop when the 15th thread is executing and signal main to finish the program. I believe that if I grasp the concept of signaling and condition waiting from main, then I can adapt this to my actual problem. If anybody can please help guide me and tell me where my logic is flawed, it would be greatly appreciated. Because currently my implementation when using a full set of alphanumeric characters and taking lengths 1-8 is crashing
#include <iostream>
#include <pthread.h>
#include <cstdlib>
#include <string>
#include <vector>
#include <algorithm>
#include <time.h>
using namespace std;
#define NUM_THREADS 100
void* testFunc(void*);
pthread_cond_t cond;
pthread_mutex_t mutex;
bool found_match;
int main(){
// Tracking execution time
clock_t t1, t2;
t1 = clock();
// Condition variable signaled from other thread
// Mutex to exclusively update bool
pthread_cond_init(&cond, NULL);
pthread_mutex_init(&mutex, NULL);
found_match = false;
// Spawn NUM_THREADS pthreads
pthread_t threads[NUM_THREADS];
int id[NUM_THREADS];
for(int i = 0; i < NUM_THREADS; i++){
id[i] = i;
pthread_create(&threads[i], NULL, testFunc, &id[i]);
}
pthread_mutex_lock(&mutex);
while(!found_match){
pthread_cond_wait(&cond, &mutex);
}
pthread_mutex_unlock(&mutex);
// Cleaning up condition variable and mutex
pthread_cond_destroy(&cond);
pthread_mutex_destroy(&mutex);
cout << "Hello from main thread!" << endl;
t2 = clock();
cout << "Time elapsed: " << (t2 - t1)/(double)CLOCKS_PER_SEC << endl;
return 0;
}
void* testFunc(void* arg){
int* int_arg = (int*) arg;
int id = *int_arg + 1;
if(found_match){
pthread_exit(NULL);
}
else if((found_match == false) && (id == 15)){
pthread_mutex_lock(&mutex);
cout << "Hello from Thread ID: " << id << endl;
found_match = true;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
cout << "Hello from Thread ID: " << id << endl;
pthread_exit(NULL);
}
c++ multithreading recursion pthreads
Threads are executed concurrently, so you cannot predict when(found_match == false) && (id == 15)
is performed. This statment in thread withid=15
might be executed when 50 other threads performed this line. Introduce global variableint counter=0
; increment it with some protectionlock_mutex; ++counter; if (counter == 15){found_match = true; signal cond var in main} unlock_mutex;
when counter reaches 15 you can signal main function.
– rafix07
Nov 12 at 13:36
@rafix07 Thank you. To extend on what I’m actually trying to solve, say each thread hasn’t completed its work, is there a way such that when main receives the signal, it can signal all the child pthreads to end if they are still executing? I feel like I’d have to have some loop in my thread function so each one only does work while some conditional, but also this is confusing because I don’t want to repeat the work over and over
– Richard S
Nov 12 at 14:46
With pthreads API you can usepthread_cancel
to send a cancellation request to thread, then thread is stopped in some cancellation points (these points are the calls of functions like pthread_cond_wait or you put cancellation point directly by callpthread_testcancel
function). Instead using pthread_cancel you may add some checkpoints (not one point, but many) into your thread function, for example testingfound_match
which stop the exeuction of function by callpthread_exit
.
– rafix07
Nov 12 at 15:45
Ok yes just took a look at the manual for pthread_cancel. My problem is that the work I’m doing is a recursive function, not a loop, so any suggestion on adding cancel points? If you look above the function “void* MD5Hashes” is what each pthread calls but the actual work is done when each pthread function calls MD5Hashes (non void* version above) which does work recursively
– Richard S
Nov 12 at 16:27
Note that pthread_cancel does not work well in C++, you should shut down your threads cleanly instead (for example, set an atomic flag and check in child threads, send a char over a pipe to threads that wait in select() etc). skaark.wordpress.com/2010/08/26/…
– Erik Alapää
Nov 14 at 9:41
add a comment |
up vote
-1
down vote
favorite
up vote
-1
down vote
favorite
My attempt to describe the problem:
I am trying to create all possible permutations of a certain length from a set of 6 characters - for example {A,B,C,D,E,F} - and hash each permutation using an MD5 cryptography function which hashes my original permutation into a string of 32 characters and stores it in a vector. I want to have 6 vectors of hashes where each vector is for permutations of lengths 1 through 6 (Example: vector1 stores hashes of permutations of length 1, vector2 for length 2, etc.)
So I have a function that recursively creates the permutations of a certain length from the set of characters, MD5 hashes each permutation, then stores each into a vector. Here is the function:
void MD5Hashes(vector<string>& vec, const char str, string prefix, const int n, const int length){
if(length == 1){
for(int j = 0; j < n; j++){
vec.push_back(md5(prefix + str[j])); // MD5 hash and push_back
}
}
else{
for(int i = 0; i < n; i++){
MD5Hashes(vec, str, prefix + str[i], n, length - 1);
}
}
}
So now what I'm aiming for is to create 6 pthreads from main, where each pthread uses the function above to create the permutations of appropriate length (Example: thread1 creates permutations of length 1 then hashes and stores into a vector, thread2 does length2, etc.) however the whole point to this is that I have my own chosen string let's say "ABC" and its MD5 hash which is a string of 32 characters - and I want to see if my hash matches any of the ones created by my pthreads. So in this case since my string is "ABC" of length 3, thread 3 is in charge of creating this permutation "ABC" from the set of characters so their should be a match within the hashes that this thread created.
My actual problem:
I want to be able to find a matching hash while creating the permutations and its hash in each pthread - and somehow signal that a match has been found to main indicating that a match has been found. Then main should kill all child pthreads since the match has been found and there is no need to continue creating permutations and their hashes. The following is my implementation without trying to signal:
#include <iostream>
#include <pthread.h>
#include <cstdlib>
#include <string>
#include <vector>
#include <algorithm>
#include <time.h>
#include "md5.h"
using namespace std;
#define NUM_THREADS 6 // Number of pthreads
#define SIZE_ASCII 6 // sizeof str below, set of characters to create permutations from
char str = {'A','B','C','D','E','F'};
// Struct object mainly used to store the permutations of lengths 1-6
struct HashStruct{
vector<string> hashes; // Stores MD5 hashes for permutations of certain length
string prefix; // Permutation
int length; // Length of each pre-hashed permutation
int identifier;
} perms_one, perms_two, perms_three, perms_four, perms_five, perms_six; // Six structs, one for each length of pre-hashed permutations
// Vector of HashStructs
vector<HashStruct>perms;
// Produce MD5 hashes from permutations of certain length from characters
// Then searches for matching MD5 hash
void MD5Hashes(vector<string>&, const char*, string, const int, const int);
// pthread function call for MD5Hashes
void *MD5Hashes(void*);
// Pre-hashed password
string password = "BCEF";
// MD5 hashed password - we are looking to match this in each pthread
string password_hash = md5(password);
int main(){
// Initializing vector of HashStruct elements - each struct element in vector used for MD5 hashing of permutations, then matching
perms.push_back(perms_one); perms.push_back(perms_two); perms.push_back(perms_three); perms.push_back(perms_four);
perms.push_back(perms_five); perms.push_back(perms_six);
for(int i = 0; i < perms.size(); i++){
perms[i].prefix = "";
perms[i].length = i + 1;
perms[i].identifier = i + 1;
}
// Timing program run time
clock_t t1, t2;
t1 = clock();
// Spawning pthreads - one for ineach set of permutations of lengths 1 through 8
pthread_t threads[NUM_THREADS];
int id[NUM_THREADS];
for(int i = 0; i < NUM_THREADS; i++){
id[i] = i;
pthread_create(&threads[i], NULL, MD5Hashes, &id[i]);
}
for(int i = 0; i < NUM_THREADS; i++){
pthread_join(threads[i], NULL);
}
// End run time
t2 = clock();
cout << "nTime elapsed: " << (t2-t1)/(double)CLOCKS_PER_SEC << endl << endl;
return 0;
}
// Method produces sizeof(str) ^ length permutations, where length is length number of characters from pre-hashed permutation
void MD5Hashes(vector<string>& vec, const char str, string prefix, const int n, const int length){
if(length == 1){
for(int j = 0; j < n; j++){
vec.push_back(md5(prefix + str[j])); // MD5 hash and push_back
}
}
else{
for(int i = 0; i < n; i++){
MD5Hashes(vec, str, prefix + str[i], n, length - 1);
}
}
}
// pthread MD5Hashes call method: first produces hashes then searches for match
void* MD5Hashes(void* arg){
int* int_arg = (int*) arg; // get the int argument which will be used as index to access HashStruct from perms[i]
int index = *int_arg;
struct HashStruct* perm = (struct HashStruct*)&perms[index];
MD5Hashes(perm->hashes, str, perm->prefix, SIZE_ASCII, perm->length);
// Search for matching hash
if(std::find(perm->hashes.begin(), perm->hashes.end(), password_hash) != perm->hashes.end()){
cout << "MATCHING HASH FOUND" << endl;
cout << "Found in thread of lengths: " << perm->identifier << endl;
cout << "MD5 Hash: " << password_hash << endl;
cout << "Password: " << password << endl;
pthread_exit(NULL);
}
pthread_exit(NULL);
}
Exploring signaling to main using conditional variable and mutex:
The following is a snippet of code from an unrelated attempt to the problem above. The point is that I am creating 100 pthreads and want to stop when the 15th thread is executing and signal main to finish the program. I believe that if I grasp the concept of signaling and condition waiting from main, then I can adapt this to my actual problem. If anybody can please help guide me and tell me where my logic is flawed, it would be greatly appreciated. Because currently my implementation when using a full set of alphanumeric characters and taking lengths 1-8 is crashing
#include <iostream>
#include <pthread.h>
#include <cstdlib>
#include <string>
#include <vector>
#include <algorithm>
#include <time.h>
using namespace std;
#define NUM_THREADS 100
void* testFunc(void*);
pthread_cond_t cond;
pthread_mutex_t mutex;
bool found_match;
int main(){
// Tracking execution time
clock_t t1, t2;
t1 = clock();
// Condition variable signaled from other thread
// Mutex to exclusively update bool
pthread_cond_init(&cond, NULL);
pthread_mutex_init(&mutex, NULL);
found_match = false;
// Spawn NUM_THREADS pthreads
pthread_t threads[NUM_THREADS];
int id[NUM_THREADS];
for(int i = 0; i < NUM_THREADS; i++){
id[i] = i;
pthread_create(&threads[i], NULL, testFunc, &id[i]);
}
pthread_mutex_lock(&mutex);
while(!found_match){
pthread_cond_wait(&cond, &mutex);
}
pthread_mutex_unlock(&mutex);
// Cleaning up condition variable and mutex
pthread_cond_destroy(&cond);
pthread_mutex_destroy(&mutex);
cout << "Hello from main thread!" << endl;
t2 = clock();
cout << "Time elapsed: " << (t2 - t1)/(double)CLOCKS_PER_SEC << endl;
return 0;
}
void* testFunc(void* arg){
int* int_arg = (int*) arg;
int id = *int_arg + 1;
if(found_match){
pthread_exit(NULL);
}
else if((found_match == false) && (id == 15)){
pthread_mutex_lock(&mutex);
cout << "Hello from Thread ID: " << id << endl;
found_match = true;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
cout << "Hello from Thread ID: " << id << endl;
pthread_exit(NULL);
}
c++ multithreading recursion pthreads
My attempt to describe the problem:
I am trying to create all possible permutations of a certain length from a set of 6 characters - for example {A,B,C,D,E,F} - and hash each permutation using an MD5 cryptography function which hashes my original permutation into a string of 32 characters and stores it in a vector. I want to have 6 vectors of hashes where each vector is for permutations of lengths 1 through 6 (Example: vector1 stores hashes of permutations of length 1, vector2 for length 2, etc.)
So I have a function that recursively creates the permutations of a certain length from the set of characters, MD5 hashes each permutation, then stores each into a vector. Here is the function:
void MD5Hashes(vector<string>& vec, const char str, string prefix, const int n, const int length){
if(length == 1){
for(int j = 0; j < n; j++){
vec.push_back(md5(prefix + str[j])); // MD5 hash and push_back
}
}
else{
for(int i = 0; i < n; i++){
MD5Hashes(vec, str, prefix + str[i], n, length - 1);
}
}
}
So now what I'm aiming for is to create 6 pthreads from main, where each pthread uses the function above to create the permutations of appropriate length (Example: thread1 creates permutations of length 1 then hashes and stores into a vector, thread2 does length2, etc.) however the whole point to this is that I have my own chosen string let's say "ABC" and its MD5 hash which is a string of 32 characters - and I want to see if my hash matches any of the ones created by my pthreads. So in this case since my string is "ABC" of length 3, thread 3 is in charge of creating this permutation "ABC" from the set of characters so their should be a match within the hashes that this thread created.
My actual problem:
I want to be able to find a matching hash while creating the permutations and its hash in each pthread - and somehow signal that a match has been found to main indicating that a match has been found. Then main should kill all child pthreads since the match has been found and there is no need to continue creating permutations and their hashes. The following is my implementation without trying to signal:
#include <iostream>
#include <pthread.h>
#include <cstdlib>
#include <string>
#include <vector>
#include <algorithm>
#include <time.h>
#include "md5.h"
using namespace std;
#define NUM_THREADS 6 // Number of pthreads
#define SIZE_ASCII 6 // sizeof str below, set of characters to create permutations from
char str = {'A','B','C','D','E','F'};
// Struct object mainly used to store the permutations of lengths 1-6
struct HashStruct{
vector<string> hashes; // Stores MD5 hashes for permutations of certain length
string prefix; // Permutation
int length; // Length of each pre-hashed permutation
int identifier;
} perms_one, perms_two, perms_three, perms_four, perms_five, perms_six; // Six structs, one for each length of pre-hashed permutations
// Vector of HashStructs
vector<HashStruct>perms;
// Produce MD5 hashes from permutations of certain length from characters
// Then searches for matching MD5 hash
void MD5Hashes(vector<string>&, const char*, string, const int, const int);
// pthread function call for MD5Hashes
void *MD5Hashes(void*);
// Pre-hashed password
string password = "BCEF";
// MD5 hashed password - we are looking to match this in each pthread
string password_hash = md5(password);
int main(){
// Initializing vector of HashStruct elements - each struct element in vector used for MD5 hashing of permutations, then matching
perms.push_back(perms_one); perms.push_back(perms_two); perms.push_back(perms_three); perms.push_back(perms_four);
perms.push_back(perms_five); perms.push_back(perms_six);
for(int i = 0; i < perms.size(); i++){
perms[i].prefix = "";
perms[i].length = i + 1;
perms[i].identifier = i + 1;
}
// Timing program run time
clock_t t1, t2;
t1 = clock();
// Spawning pthreads - one for ineach set of permutations of lengths 1 through 8
pthread_t threads[NUM_THREADS];
int id[NUM_THREADS];
for(int i = 0; i < NUM_THREADS; i++){
id[i] = i;
pthread_create(&threads[i], NULL, MD5Hashes, &id[i]);
}
for(int i = 0; i < NUM_THREADS; i++){
pthread_join(threads[i], NULL);
}
// End run time
t2 = clock();
cout << "nTime elapsed: " << (t2-t1)/(double)CLOCKS_PER_SEC << endl << endl;
return 0;
}
// Method produces sizeof(str) ^ length permutations, where length is length number of characters from pre-hashed permutation
void MD5Hashes(vector<string>& vec, const char str, string prefix, const int n, const int length){
if(length == 1){
for(int j = 0; j < n; j++){
vec.push_back(md5(prefix + str[j])); // MD5 hash and push_back
}
}
else{
for(int i = 0; i < n; i++){
MD5Hashes(vec, str, prefix + str[i], n, length - 1);
}
}
}
// pthread MD5Hashes call method: first produces hashes then searches for match
void* MD5Hashes(void* arg){
int* int_arg = (int*) arg; // get the int argument which will be used as index to access HashStruct from perms[i]
int index = *int_arg;
struct HashStruct* perm = (struct HashStruct*)&perms[index];
MD5Hashes(perm->hashes, str, perm->prefix, SIZE_ASCII, perm->length);
// Search for matching hash
if(std::find(perm->hashes.begin(), perm->hashes.end(), password_hash) != perm->hashes.end()){
cout << "MATCHING HASH FOUND" << endl;
cout << "Found in thread of lengths: " << perm->identifier << endl;
cout << "MD5 Hash: " << password_hash << endl;
cout << "Password: " << password << endl;
pthread_exit(NULL);
}
pthread_exit(NULL);
}
Exploring signaling to main using conditional variable and mutex:
The following is a snippet of code from an unrelated attempt to the problem above. The point is that I am creating 100 pthreads and want to stop when the 15th thread is executing and signal main to finish the program. I believe that if I grasp the concept of signaling and condition waiting from main, then I can adapt this to my actual problem. If anybody can please help guide me and tell me where my logic is flawed, it would be greatly appreciated. Because currently my implementation when using a full set of alphanumeric characters and taking lengths 1-8 is crashing
#include <iostream>
#include <pthread.h>
#include <cstdlib>
#include <string>
#include <vector>
#include <algorithm>
#include <time.h>
using namespace std;
#define NUM_THREADS 100
void* testFunc(void*);
pthread_cond_t cond;
pthread_mutex_t mutex;
bool found_match;
int main(){
// Tracking execution time
clock_t t1, t2;
t1 = clock();
// Condition variable signaled from other thread
// Mutex to exclusively update bool
pthread_cond_init(&cond, NULL);
pthread_mutex_init(&mutex, NULL);
found_match = false;
// Spawn NUM_THREADS pthreads
pthread_t threads[NUM_THREADS];
int id[NUM_THREADS];
for(int i = 0; i < NUM_THREADS; i++){
id[i] = i;
pthread_create(&threads[i], NULL, testFunc, &id[i]);
}
pthread_mutex_lock(&mutex);
while(!found_match){
pthread_cond_wait(&cond, &mutex);
}
pthread_mutex_unlock(&mutex);
// Cleaning up condition variable and mutex
pthread_cond_destroy(&cond);
pthread_mutex_destroy(&mutex);
cout << "Hello from main thread!" << endl;
t2 = clock();
cout << "Time elapsed: " << (t2 - t1)/(double)CLOCKS_PER_SEC << endl;
return 0;
}
void* testFunc(void* arg){
int* int_arg = (int*) arg;
int id = *int_arg + 1;
if(found_match){
pthread_exit(NULL);
}
else if((found_match == false) && (id == 15)){
pthread_mutex_lock(&mutex);
cout << "Hello from Thread ID: " << id << endl;
found_match = true;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
cout << "Hello from Thread ID: " << id << endl;
pthread_exit(NULL);
}
c++ multithreading recursion pthreads
c++ multithreading recursion pthreads
asked Nov 12 at 1:02
Richard S
41
41
Threads are executed concurrently, so you cannot predict when(found_match == false) && (id == 15)
is performed. This statment in thread withid=15
might be executed when 50 other threads performed this line. Introduce global variableint counter=0
; increment it with some protectionlock_mutex; ++counter; if (counter == 15){found_match = true; signal cond var in main} unlock_mutex;
when counter reaches 15 you can signal main function.
– rafix07
Nov 12 at 13:36
@rafix07 Thank you. To extend on what I’m actually trying to solve, say each thread hasn’t completed its work, is there a way such that when main receives the signal, it can signal all the child pthreads to end if they are still executing? I feel like I’d have to have some loop in my thread function so each one only does work while some conditional, but also this is confusing because I don’t want to repeat the work over and over
– Richard S
Nov 12 at 14:46
With pthreads API you can usepthread_cancel
to send a cancellation request to thread, then thread is stopped in some cancellation points (these points are the calls of functions like pthread_cond_wait or you put cancellation point directly by callpthread_testcancel
function). Instead using pthread_cancel you may add some checkpoints (not one point, but many) into your thread function, for example testingfound_match
which stop the exeuction of function by callpthread_exit
.
– rafix07
Nov 12 at 15:45
Ok yes just took a look at the manual for pthread_cancel. My problem is that the work I’m doing is a recursive function, not a loop, so any suggestion on adding cancel points? If you look above the function “void* MD5Hashes” is what each pthread calls but the actual work is done when each pthread function calls MD5Hashes (non void* version above) which does work recursively
– Richard S
Nov 12 at 16:27
Note that pthread_cancel does not work well in C++, you should shut down your threads cleanly instead (for example, set an atomic flag and check in child threads, send a char over a pipe to threads that wait in select() etc). skaark.wordpress.com/2010/08/26/…
– Erik Alapää
Nov 14 at 9:41
add a comment |
Threads are executed concurrently, so you cannot predict when(found_match == false) && (id == 15)
is performed. This statment in thread withid=15
might be executed when 50 other threads performed this line. Introduce global variableint counter=0
; increment it with some protectionlock_mutex; ++counter; if (counter == 15){found_match = true; signal cond var in main} unlock_mutex;
when counter reaches 15 you can signal main function.
– rafix07
Nov 12 at 13:36
@rafix07 Thank you. To extend on what I’m actually trying to solve, say each thread hasn’t completed its work, is there a way such that when main receives the signal, it can signal all the child pthreads to end if they are still executing? I feel like I’d have to have some loop in my thread function so each one only does work while some conditional, but also this is confusing because I don’t want to repeat the work over and over
– Richard S
Nov 12 at 14:46
With pthreads API you can usepthread_cancel
to send a cancellation request to thread, then thread is stopped in some cancellation points (these points are the calls of functions like pthread_cond_wait or you put cancellation point directly by callpthread_testcancel
function). Instead using pthread_cancel you may add some checkpoints (not one point, but many) into your thread function, for example testingfound_match
which stop the exeuction of function by callpthread_exit
.
– rafix07
Nov 12 at 15:45
Ok yes just took a look at the manual for pthread_cancel. My problem is that the work I’m doing is a recursive function, not a loop, so any suggestion on adding cancel points? If you look above the function “void* MD5Hashes” is what each pthread calls but the actual work is done when each pthread function calls MD5Hashes (non void* version above) which does work recursively
– Richard S
Nov 12 at 16:27
Note that pthread_cancel does not work well in C++, you should shut down your threads cleanly instead (for example, set an atomic flag and check in child threads, send a char over a pipe to threads that wait in select() etc). skaark.wordpress.com/2010/08/26/…
– Erik Alapää
Nov 14 at 9:41
Threads are executed concurrently, so you cannot predict when
(found_match == false) && (id == 15)
is performed. This statment in thread with id=15
might be executed when 50 other threads performed this line. Introduce global variable int counter=0
; increment it with some protection lock_mutex; ++counter; if (counter == 15){found_match = true; signal cond var in main} unlock_mutex;
when counter reaches 15 you can signal main function.– rafix07
Nov 12 at 13:36
Threads are executed concurrently, so you cannot predict when
(found_match == false) && (id == 15)
is performed. This statment in thread with id=15
might be executed when 50 other threads performed this line. Introduce global variable int counter=0
; increment it with some protection lock_mutex; ++counter; if (counter == 15){found_match = true; signal cond var in main} unlock_mutex;
when counter reaches 15 you can signal main function.– rafix07
Nov 12 at 13:36
@rafix07 Thank you. To extend on what I’m actually trying to solve, say each thread hasn’t completed its work, is there a way such that when main receives the signal, it can signal all the child pthreads to end if they are still executing? I feel like I’d have to have some loop in my thread function so each one only does work while some conditional, but also this is confusing because I don’t want to repeat the work over and over
– Richard S
Nov 12 at 14:46
@rafix07 Thank you. To extend on what I’m actually trying to solve, say each thread hasn’t completed its work, is there a way such that when main receives the signal, it can signal all the child pthreads to end if they are still executing? I feel like I’d have to have some loop in my thread function so each one only does work while some conditional, but also this is confusing because I don’t want to repeat the work over and over
– Richard S
Nov 12 at 14:46
With pthreads API you can use
pthread_cancel
to send a cancellation request to thread, then thread is stopped in some cancellation points (these points are the calls of functions like pthread_cond_wait or you put cancellation point directly by call pthread_testcancel
function). Instead using pthread_cancel you may add some checkpoints (not one point, but many) into your thread function, for example testing found_match
which stop the exeuction of function by call pthread_exit
.– rafix07
Nov 12 at 15:45
With pthreads API you can use
pthread_cancel
to send a cancellation request to thread, then thread is stopped in some cancellation points (these points are the calls of functions like pthread_cond_wait or you put cancellation point directly by call pthread_testcancel
function). Instead using pthread_cancel you may add some checkpoints (not one point, but many) into your thread function, for example testing found_match
which stop the exeuction of function by call pthread_exit
.– rafix07
Nov 12 at 15:45
Ok yes just took a look at the manual for pthread_cancel. My problem is that the work I’m doing is a recursive function, not a loop, so any suggestion on adding cancel points? If you look above the function “void* MD5Hashes” is what each pthread calls but the actual work is done when each pthread function calls MD5Hashes (non void* version above) which does work recursively
– Richard S
Nov 12 at 16:27
Ok yes just took a look at the manual for pthread_cancel. My problem is that the work I’m doing is a recursive function, not a loop, so any suggestion on adding cancel points? If you look above the function “void* MD5Hashes” is what each pthread calls but the actual work is done when each pthread function calls MD5Hashes (non void* version above) which does work recursively
– Richard S
Nov 12 at 16:27
Note that pthread_cancel does not work well in C++, you should shut down your threads cleanly instead (for example, set an atomic flag and check in child threads, send a char over a pipe to threads that wait in select() etc). skaark.wordpress.com/2010/08/26/…
– Erik Alapää
Nov 14 at 9:41
Note that pthread_cancel does not work well in C++, you should shut down your threads cleanly instead (for example, set an atomic flag and check in child threads, send a char over a pipe to threads that wait in select() etc). skaark.wordpress.com/2010/08/26/…
– Erik Alapää
Nov 14 at 9:41
add a comment |
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53254800%2fsignaling-main-thread-to-finish-the-program-when-any-child-pthread-meets-conditi%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Threads are executed concurrently, so you cannot predict when
(found_match == false) && (id == 15)
is performed. This statment in thread withid=15
might be executed when 50 other threads performed this line. Introduce global variableint counter=0
; increment it with some protectionlock_mutex; ++counter; if (counter == 15){found_match = true; signal cond var in main} unlock_mutex;
when counter reaches 15 you can signal main function.– rafix07
Nov 12 at 13:36
@rafix07 Thank you. To extend on what I’m actually trying to solve, say each thread hasn’t completed its work, is there a way such that when main receives the signal, it can signal all the child pthreads to end if they are still executing? I feel like I’d have to have some loop in my thread function so each one only does work while some conditional, but also this is confusing because I don’t want to repeat the work over and over
– Richard S
Nov 12 at 14:46
With pthreads API you can use
pthread_cancel
to send a cancellation request to thread, then thread is stopped in some cancellation points (these points are the calls of functions like pthread_cond_wait or you put cancellation point directly by callpthread_testcancel
function). Instead using pthread_cancel you may add some checkpoints (not one point, but many) into your thread function, for example testingfound_match
which stop the exeuction of function by callpthread_exit
.– rafix07
Nov 12 at 15:45
Ok yes just took a look at the manual for pthread_cancel. My problem is that the work I’m doing is a recursive function, not a loop, so any suggestion on adding cancel points? If you look above the function “void* MD5Hashes” is what each pthread calls but the actual work is done when each pthread function calls MD5Hashes (non void* version above) which does work recursively
– Richard S
Nov 12 at 16:27
Note that pthread_cancel does not work well in C++, you should shut down your threads cleanly instead (for example, set an atomic flag and check in child threads, send a char over a pipe to threads that wait in select() etc). skaark.wordpress.com/2010/08/26/…
– Erik Alapää
Nov 14 at 9:41