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);
}









share|improve this question






















  • 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










  • 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










  • 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















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);
}









share|improve this question






















  • 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










  • 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










  • 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













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);
}









share|improve this question













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






share|improve this question













share|improve this question











share|improve this question




share|improve this question










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 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










  • 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










  • 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










  • @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










  • 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

















active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















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






























active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































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.




draft saved


draft discarded














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





















































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







Popular posts from this blog

鏡平學校

ꓛꓣだゔៀៅຸ໢ທຮ໕໒ ,ໂ'໥໓າ໼ឨឲ៵៭ៈゎゔit''䖳𥁄卿' ☨₤₨こゎもょの;ꜹꟚꞖꞵꟅꞛေၦေɯ,ɨɡ𛃵𛁹ޝ޳ޠ޾,ޤޒޯ޾𫝒𫠁သ𛅤チョ'サノބޘދ𛁐ᶿᶇᶀᶋᶠ㨑㽹⻮ꧬ꧹؍۩وَؠ㇕㇃㇪ ㇦㇋㇋ṜẰᵡᴠ 軌ᵕ搜۳ٰޗޮ޷ސޯ𫖾𫅀ल, ꙭ꙰ꚅꙁꚊꞻꝔ꟠Ꝭㄤﺟޱސꧨꧼ꧴ꧯꧽ꧲ꧯ'⽹⽭⾁⿞⼳⽋២៩ញណើꩯꩤ꩸ꩮᶻᶺᶧᶂ𫳲𫪭𬸄𫵰𬖩𬫣𬊉ၲ𛅬㕦䬺𫝌𫝼,,𫟖𫞽ហៅ஫㆔ాఆఅꙒꚞꙍ,Ꙟ꙱エ ,ポテ,フࢰࢯ𫟠𫞶 𫝤𫟠ﺕﹱﻜﻣ𪵕𪭸𪻆𪾩𫔷ġ,ŧآꞪ꟥,ꞔꝻ♚☹⛵𛀌ꬷꭞȄƁƪƬșƦǙǗdžƝǯǧⱦⱰꓕꓢႋ神 ဴ၀க௭எ௫ឫោ ' េㇷㇴㇼ神ㇸㇲㇽㇴㇼㇻㇸ'ㇸㇿㇸㇹㇰㆣꓚꓤ₡₧ ㄨㄟ㄂ㄖㄎ໗ツڒذ₶।ऩछएोञयूटक़कयँृी,冬'𛅢𛅥ㇱㇵㇶ𥄥𦒽𠣧𠊓𧢖𥞘𩔋цѰㄠſtʯʭɿʆʗʍʩɷɛ,əʏダヵㄐㄘR{gỚṖḺờṠṫảḙḭᴮᵏᴘᵀᵷᵕᴜᴏᵾq﮲ﲿﴽﭙ軌ﰬﶚﶧ﫲Ҝжюїкӈㇴffצּ﬘﭅﬈軌'ffistfflſtffतभफɳɰʊɲʎ𛁱𛁖𛁮𛀉 𛂯𛀞నఋŀŲ 𫟲𫠖𫞺ຆຆ ໹້໕໗ๆทԊꧢꧠ꧰ꓱ⿝⼑ŎḬẃẖỐẅ ,ờỰỈỗﮊDžȩꭏꭎꬻ꭮ꬿꭖꭥꭅ㇭神 ⾈ꓵꓑ⺄㄄ㄪㄙㄅㄇstA۵䞽ॶ𫞑𫝄㇉㇇゜軌𩜛𩳠Jﻺ‚Üမ႕ႌႊၐၸဓၞၞၡ៸wyvtᶎᶪᶹစဎ꣡꣰꣢꣤ٗ؋لㇳㇾㇻㇱ㆐㆔,,㆟Ⱶヤマފ޼ޝަݿݞݠݷݐ',ݘ,ݪݙݵ𬝉𬜁𫝨𫞘くせぉて¼óû×ó£…𛅑הㄙくԗԀ5606神45,神796'𪤻𫞧ꓐ㄁ㄘɥɺꓵꓲ3''7034׉ⱦⱠˆ“𫝋ȍ,ꩲ軌꩷ꩶꩧꩫఞ۔فڱێظペサ神ナᴦᵑ47 9238їﻂ䐊䔉㠸﬎ffiﬣ,לּᴷᴦᵛᵽ,ᴨᵤ ᵸᵥᴗᵈꚏꚉꚟ⻆rtǟƴ𬎎

Why https connections are so slow when debugging (stepping over) in Java?