Issue
I am writing a program that reads a large amount of dynamic data. I would like to use multi-threading to speed this process up. I understand that it is up to the operating system on how to handle created threads (thread priority, etc), which I believe is the reason for my unexpected results, however, I still do not know a solution.
Code:
int multiplier = rowCount / 20;
Debug.WriteLine("Row count is " + rowCount + "...");
Debug.WriteLine("Using 20 threads to complete job...");
Debug.WriteLine("Using " + multiplier + " as multiplier...");
for (int i = 1; i <= 20; i++) {
new Thread(() => {
int startRow = ((multiplier * i) - multiplier) + 1;
int endRow = multiplier * i;
if (i == 20) {
endRow = rowCount;
}
Debug.WriteLine(" [THREAD " + i + "] start row: " + startRow + ", end row : " + endRow);
for (int row = startRow; row <= endRow; row++) {
for (int column = 1; column <= columnCount; column++) {
//...data is read here
}
}
}).Start();
}
Actual result (it appears that my issue is the child thread not "reading" the ‘i’ variable "correctly", which makes sense considering how threads work, I just do not know how to fix it):
Row count is 2209...
Using 20 threads to complete job...
Using 110 as multiplier...
[THREAD 4] start row: 331, end row : 440
[THREAD 4] start row: 331, end row : 440
[THREAD 5] start row: 441, end row : 550
[THREAD 5] start row: 441, end row : 550
[THREAD 6] start row: 551, end row : 660
[THREAD 7] start row: 661, end row : 770
[THREAD 9] start row: 881, end row : 990
[THREAD 9] start row: 881, end row : 990
[THREAD 11] start row: 1101, end row : 1210
[THREAD 11] start row: 1101, end row : 1210
[THREAD 12] start row: 1211, end row : 1320
[THREAD 14] start row: 1431, end row : 1540
[THREAD 15] start row: 1541, end row : 1650
[THREAD 15] start row: 1541, end row : 1650
[THREAD 16] start row: 1651, end row : 1760
[THREAD 17] start row: 1761, end row : 1870
[THREAD 19] start row: 1981, end row : 2090
[THREAD 20] start row: 2091, end row : 2209
[THREAD 20] start row: 2091, end row : 2209
[THREAD 21] start row: 2201, end row : 2310
Expected result (this is the result of simply not using threads, meaning commenting out the lambda expression):
Row count is 2209...
Using 20 threads to complete job...
Using 110 as multiplier...
[THREAD 1] start row: 1, end row : 110
[THREAD 2] start row: 111, end row : 220
[THREAD 3] start row: 221, end row : 330
[THREAD 4] start row: 331, end row : 440
[THREAD 5] start row: 441, end row : 550
[THREAD 6] start row: 551, end row : 660
[THREAD 7] start row: 661, end row : 770
[THREAD 8] start row: 771, end row : 880
[THREAD 9] start row: 881, end row : 990
[THREAD 10] start row: 991, end row : 1100
[THREAD 11] start row: 1101, end row : 1210
[THREAD 12] start row: 1211, end row : 1320
[THREAD 13] start row: 1321, end row : 1430
[THREAD 14] start row: 1431, end row : 1540
[THREAD 15] start row: 1541, end row : 1650
[THREAD 16] start row: 1651, end row : 1760
[THREAD 17] start row: 1761, end row : 1870
[THREAD 18] start row: 1871, end row : 1980
[THREAD 19] start row: 1981, end row : 2090
[THREAD 20] start row: 2091, end row : 2209
Solution
Try moving the variables that can be calculated outside of the thread to avoid reading the shared variable i
in the thread. The threads are started without care of the surrounding loop which increments i
.
int multiplier = rowCount / 20;
Debug.WriteLine("Row count is " + rowCount + "...");
Debug.WriteLine("Using 20 threads to complete job...");
Debug.WriteLine("Using " + multiplier + " as multiplier...");
for (int i = 1; i <= 20; i++) {
int startRow = ((multiplier * i) - multiplier) + 1;
int endRow = multiplier * i;
if (i == 20) {
endRow = rowCount;
}
int nThread = i;
new Thread(() => {
Debug.WriteLine(" [THREAD " + nThread + "] start row: " + startRow + ", end row : " + endRow);
for (int row = startRow; row <= endRow; row++) {
for (int column = 1; column <= columnCount; column++) {
//...data is read here
}
}
}).Start();
}
It is apparent in the first log you shared, for example when thread 1 and 2 starts, i
is already at 4.
Answered By – user19902261
This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0