Instead of scouring through thousands of lines for error, race-check.py little utility will read the merged file one-by-one, parse and do the addition again and compare the result. (code below).
If I may see result looks promising:
With mutex line disabled, expected the possibility of race condition. with 2 threads and 20,000 loops, python found two addition that makes no sense:
Code: Select all
[root@dev]# cat race.found.log
RACE!: ['75330', '2', '75877']
RACE!: ['103486', '2', '104581']
RACE!: ['34712', '3', '35232']
RACE!: ['105220', '5', '105751']
I then reduced the CONFIG_THREAD_COUNT to 1 effectively making a single-threaded or no concurrency, main() will launch only 1 thread and do not bother with SUM, therefore only only one instance of hello() will sequentially add it thousands of times and yes, with the result, race-check.py did not find any inconsistency.[root@dev]# egrep -ir "75330:2" file.all.log -A 2 -B 2
threadNo. 0:75321:4:75325
threadNo. 0:75325:5:75330
threadNo. 0:75330:2:75877
threadNo. 0:75877:2:75879
threadNo. 0:75879:4:75883
As a next step, I am applying the mutex inside the hello and see how it goes which I haven't tried.
Code: Select all
#include <list>
#include <mutex>
#include <algorithm>
#include <thread>
#include <iostream>
#include <fstream>
#include <sstream>
#include <unistd.h>
using namespace std;
std::mutex mutex_sum;
int sum = 0;
void hello(int pId, int pStat[])
{
int pNum;
int i;
std::cout << pId << ": Hello CONCURRENT WORLD " << endl;
for (int i = 0; i < 1000000; i++ ) {
pNum = rand() % 4 + 2;
cout << pId << ": " << ", loop: " << i << endl;
// read + sum + read and write to file.
ofstream myfile;
ostringstream oss;
oss << "file-" << pId << "-" << i;
myfile.open(oss.str());
myfile << "threadNo. " << pId << ":" << sum;
sum += pNum;
myfile << ":" << pNum << ":" << sum << endl;
pStat[pId] = 1;
myfile.close();
}
std::cout << pId << ": Done sleeping exiting now..." << endl;
}
int main()
{
// Declare, initialize variables.
int i;
const int CONFIG_THREAD_COUNT = 2;
int stat[CONFIG_THREAD_COUNT];
int sum = 0;
// launch threads.
for ( i = 0; i < CONFIG_THREAD_COUNT; i ++ ) {
stat[i] = 0;
std::thread t(hello, i, stat);
t.detach();
}
cout << "Checking thread status-s..." << endl;
while (sum != CONFIG_THREAD_COUNT) {
sum = 0;
for (i = 0; i < CONFIG_THREAD_COUNT; i++) {
cout << stat[i] << ", ";
sum += stat[i];
}
cout << "main(): sum: " << sum << ". waiting for all threads to finish..." << endl;
usleep(2 * 1000000);
}
return 0;
}
Code: Select all
fp = open("file.all.log")
fpOut = open("race.found.log", 'w')
if not fp:
print "Failed to open."
line = fp.readline().strip()
counter = 0
while line:
print line
operands= line.split(":")[1:4]
print "operands: ", operands
if int(operands[0]) + int(operands[1]) != int(operands[2]):
fpOut.write("RACE!: " + str(operands) + "\n")
counter += 1
line = fp.readline().strip()
if counter == 0:
fpOut.write("No race condition found.")
print "No race condition found."
else:
print "At least one race condition found: ", counter
fp.close()
fpOut.close()