Merge sort between 2 file with thread

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
// mergefile2norecreation.cpp : definisce il punto di ingresso dell'applicazione console.
//
// Filemerge.cpp : definisce il punto di ingresso dell'applicazione console.
//

#include "stdafx.h"


int _tmain(int argc, _TCHAR* argv[])
{

TCHAR inputfile1[MAX_PATH];
TCHAR inputfile2[MAX_PATH];
TCHAR outputfile[MAX_PATH];
 
 
std::ifstream f1;
std::ifstream f2;
int flag1=1;
int flag2=1;

std::string s1;
std::string s2;

//se false , il consumatore deve scriverle
bool b1=FALSE;
bool b2=FALSE;



std::mutex m1;
std::mutex m2;
std::mutex m3;

std::condition_variable cv1;
std::condition_variable cv2;
std::condition_variable cv3;
 





 

_tcscpy_s(inputfile1,MAX_PATH,argv[1]);
_tcscpy_s(inputfile2,MAX_PATH,argv[2]);
_tcscpy_s(outputfile,MAX_PATH,argv[3]);

f1.open(inputfile1);
f2.open(inputfile2);


/*
Thread behavior is 

*get lock 
*produce string
* signal to consumer 
* wait until consumer will signal you 

*/
 


 
std::thread t1([&f1,&s1,&m1,&cv1,&b1,&cv3]()->void{
 while(1){
	std::unique_lock<std::mutex> ul1(m1);
	if(f1.good()) { 
	std::getline(f1,s1);
	}else {s1.clear(); }


	b1=true;
	cv3.notify_all();

	if(s1.empty()) {
		break;}

        while(b1==true)    cv1.wait(ul1);
		continue;
	} 
 
	 return;
 }
);

 
 
std::thread t2([&f2,&s2,&m2,&cv2,&b2,&cv3]()->void{

 while(1){
	std::unique_lock<std::mutex> ul2(m2);
	if(f2.good()) { 
	std::getline(f2,s2);
	}else{
	s2.clear();
	
	}

	b2=true;
    cv3.notify_all();

	if(s2.empty()){ 
		break;}

	while(b2==true)	cv2.wait(ul2); 
	
	}


	return ;
   



});

 


/*
Reader behavior is 

* get lock  of both thread!
* consume a string
* unlock only the thread for wich i have consumed the string 
*  
* wait that the victim thread produce something
* and repeat 

*/
 
 
 
 




while (1){ 

	{
 
  std::unique_lock<std::mutex> ul1(m1);
  while(b1==false) cv3.wait(ul1);

  std::unique_lock<std::mutex> ul2(m2);
  while(b2==false) cv3.wait(ul2);



if((s1.compare(std::string())==0) &&  (s2.compare(std::string())==0)){ break;  }

if(s1.compare(std::string())==0){  b2=false;  std::cout<<s2<<std::endl;   }
if(s2.compare(std::string())==0){  b1=false;   std::cout<<s1<<std::endl;    }

if(s1.compare(s2)<0   &&  s2.compare(std::string())!=0  &&  (s1.compare(std::string())!=0) )  {   
   b1=false; 
	std::cout<<s1<<std::endl;  }


if(s1.compare(s2)>=0  && s2.compare(std::string())!=0  &&  (s1.compare(std::string())!=0)) {  
   b2=false; 
	std::cout<<s2<<std::endl; 
} 
}
	cv1.notify_all();
	cv2.notify_all();



}


t1.join();
t2.join();


 

  
	  
	return 0;
}



Hi, There is a smart way to make a merge sort between 2 file already ordered?
I had try it ,and above there is my result,it works but i think that it's possible to do it in a smart way...

Thanks in advance
Hi, There is a smart way to make a merge sort between 2 file already ordered?
What do you mean "ordered"? They contain some data which is ordered (say tuples of int, double, string)? And where do you want to store result of sorting? Another file? Overwrite content of some file?

Assuming you have an class data which represents data containing in files for which operators >> and << for reading from and saving to stream and also operator < for comparsion are defined and your files sorted ascending:
1
2
3
4
5
6
std::ifstream  ifirst("first_input.txt");
std::ifstream isecond("second_input.txt");
std::ofstream  output("output.txt");
std::merge(std::istream_iterator<data>(ifirst),  std::istream_iterator<data>(),
           std::istream_iterator<data>(isecond), std::istream_iterator<data>(),
           std::ostream_iterator<data>(output)  );
Last edited on
Hi first of all , thans for your help.
This is the problem :

I have 2 file that contain a set of words.
In these file the word are in ascending order.
for example

File 1:
1
2
3
4
america
banana 
cactus
zebra



File 2:

1
2
red
tiger



The output file will be :


1
2
3
4
5
6
7
8
9
america
banana 
cactus
america
banana 
cactus
zebra
zebra




But i want to perform it with the thread...
A thread for each file .
The consumer riceve 2 string( 1 from each thread) , compare them

if the first is the bigger one consume it and ask to thread1 to produce another string.

if the second is the bigger one consume it and ask to thread2 to produce another string.

till the 2 file will end.

I must warn you that you won't get any perfomance boost by using threads here and actually will suffer perfomance loss: you have natural bottleneck — IO. Hard disc cannot work concurrently. Also your threads should be synchronized and that will take its toll on resources.
Yes sure,but it is not a real problem..is an exercises.
thanks :)
Topic archived. No new replies allowed.