how to use window thread

how to use multiple threads in order to reduce the time of encryption.
when i use 1 thread to encrypt 5mb file, time taken is 5 seconds but when i use 2 threads, the time takes longer, 24 seconds. i split the 5mb text into 2 parts and encrypt using 2 threads but the time is longer than using 1 thread. im running on vc++2008 intel i5 processor and 4gb memory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
string Enc(string pt)
{
byte key[ CryptoPP::AES::DEFAULT_KEYLENGTH ], iv[ CryptoPP::AES::BLOCKSIZE ];

string cip;
CryptoPP::CTR_Mode<CryptoPP::AES>::Encr… Encryptor( key, sizeof(key), iv );
CryptoPP::StringSource( pt, true,new CryptoPP::StreamTransformationFilter
( Encryptor,new CryptoPP::HexEncoder(new CryptoPP::StringSink(cip))));
return cip;
}

int main()
{

HANDLE hThreads[10];

if(NUM==1)
hThreads[0] = (HANDLE)_beginthread(Func1, 0, NULL);

if(NUM==2)
{
hThreads[0] = (HANDLE)_beginthread(Func1, 0, NULL);
hThreads[1] = (HANDLE)_beginthread(Func2, 0, NULL);
}
WaitForMultipleObjects(NUM, hThreads, TRUE, INFINITE);
}

void Func1(void *P)
{

Enc(vec.at(0));
return;
}

void Func2(void *P)
{
Enc(vec2.at(0));
return;
}


I suppose you didn't like my answer in your first thread http://www.cplusplus.com/forum/windows/59618/ ?

At least you should have changed _beginthread() to _beginthreadex().
using _begintheradex() also gives same time taken.

below is my updated code with _begintherdex()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72

void load()
{

ifstream readF ("3mb.txt");

string output; string out;

if(readF.is_open())
{
while(!readF.eof())
{
getline(readF,out);
output=output+'\n'+out;

}
readF.close();
//cout<<output<<endl;
//cout<<output.size()<<endl;
text[0]=output;


}
else
	cout<<"couldnt open file!"<<endl;

}

unsigned Counter; 
unsigned __stdcall SecondThreadFunc( void* pArguments )
{

 		cout<<"encrypting..."<<endl;
	Enc(text[0]);

    _endthreadex( 0 );
    return 0;
} 

unsigned __stdcall SecondThreadFunc2( void* pArguments )
{

 		cout<<"encrypting..."<<endl;
	//Enc(text[0]);

    _endthreadex( 0 );
    return 0;
} 

int main()
{ 
	load();
    HANDLE hThread[10];
    unsigned threadID;

	  time_t start, end;
  start =time(0);
    hThread[0] = (HANDLE)_beginthreadex( NULL, 0, &SecondThreadFunc, NULL, 0, &threadID );
hThread[1] = (HANDLE)_beginthreadex( NULL, 0, &SecondThreadFunc2, NULL, 0, &threadID );

    WaitForSingleObject( hThread[0], INFINITE );
	WaitForSingleObject( hThread[1], INFINITE );
 
    CloseHandle( hThread[0] );
	end=time(0);


cout<<"Time taken : "<<difftime(end, start) << "second(s)" << endl;


	system("pause");
}
The code in main looks roughly ok (missing CloseHandle (hThread[1])) and should correctly spawn the two worker threads that you want.

The load() function reads the text file line by line into a string object, and then a (global, I suppose?) variable called text receives a copy. Since text is indexed, I suppose it is a C array or maybe a std::vector.

Now the problem comes: How do you actually split the work of encryption here? I would imagine that you split the contents of text[0] in two (I suppose that you can save the other half in text[1]). After you do this, you call Enc() on each half. Is this what you are doing?
i use substr to split the string half. main function is the same

void load()
{

ifstream readF ("3mb.txt");

string output; string out;

if(readF.is_open())
{
while(!readF.eof())
{
getline(readF,out);
output=output+'\n'+out;

}
readF.close();
//cout<<output<<endl;
//cout<<output.size()<<endl;
int div = output.size()/2;

text[0]=output.substr(0,div);
text[1] = output.substr(div,output.size());


}
else
cout<<"couldnt open file!"<<endl;

}

unsigned Counter;
unsigned __stdcall SecondThreadFunc( void* pArguments )
{

cout<<"encrypting..."<<endl;
Enc(text[0]);

_endthreadex( 0 );
return 0;
}

unsigned __stdcall SecondThreadFunc2( void* pArguments )
{

cout<<"encrypting..."<<endl;
Enc(text[1]);

_endthreadex( 0 );
return 0;
}
Ok, yes, that is Ok for the most part and should perform the encryption in two different threads. Are you obtaining incorrect results from this? Have you verified that the encryption takes place correctly?

I see that you use some encryption classes, so I don't think I can test myself, so come back here to post your results.
when encrypt with 2 threads, the time taken is double of using 1 thread time taken. with 1 thread time taken is 5 seconds for 3 mb file, with 2 threads it takes 10 seconds. is it because of threads use same encryption function?


encrypting...
encrypting...
Time taken : 10 second(s)
It could be that text[1] needs to be:

1
2
3
4
5
text[1] = output.substr(div);
//Your code says:  Make text[1] a std::string that is a copy of output starting at postion div,
//but being of length output.size(), which is 3 MB, not the 1.5MB that you want.
//The above fix is the same as this:
text[1] = output.substr(div, std::string::npos);


For more information about std::string::substr(), you should consult this website's reference.

What I think it is happening is that you are encrypting 1.5MB in text[0], and then 3MB in text[1] instead of 1.5MB.

But so we are clear, starting up threads have some cost, and you depend on what the OS is doing to get some CPU time for them. So don't expect super dramatic time reductions all the time you multi-thread, although yes, in general you should see the work done faster.
To encrypt a file more quickly, you should look at async file i/o, which would mean switching to Windows native File API calls.
Last edited on
Topic archived. No new replies allowed.