.NET 4.0: Please help me with this tasks issue - multithreading

Simple copy pasta here:
static void Main(string[] args)
{
List<Task> Tasks = new List<Task>();
Random r = new Random();
for (int o = 0; o < 5; o++)
Tasks.Add(Task.Factory.StartNew(() => { int i = r.Next(0, 3000); Thread.Sleep(i); Console.WriteLine("{0}: {1}", o, i); }));
Task.WaitAll(Tasks.ToArray());
Console.Read();
}
When you run that, you will get something like this:
5: 98
5: 198
5: 658
5: 1149
5: 1300
What am I not understanding about this? Writing each iteration of o is showing as 5 for all threads when I'd expect to see numbers 0 through 4 in random order.
I tried using an actual method instead of anonymous and it does the same thing. What am I missing?
Edit: I just found the problem with my very first post and edited the question, so sorry if you answered about the improper order problem. However, I am curious as to why o is not writing properly.

() =>
{
int i = r.Next(0, 3000);
Thread.Sleep(i);
Console.WriteLine("{0}: {1}", o, i);
})
Your are closing over your loop variable o with the delegate you use for your task - by the time it is executed your loop has finished and you only get the end value 5 for o. Remember you are creating a closure over the loop variable, not it's current value - the value is only evaluated when the delegate is executed once the task is started.
You have to create a local copy of the loop variable instead, which you can then use safely:
for (int o = 0; o < 5; o++)
{
int localO = o;
Tasks.Add(Task.Factory.StartNew(() => { int i = r.Next(0, 3000); Thread.Sleep(i); Console.WriteLine("{0}: {1}", localO, i); }));
}

There are at least two problems here.
The problem with o having the value of 5 on every iteration is one of those "gotchas" of lexical closures. If you want o to capture its current value, you must create a locally scoped variable inside your loop and use that in your lambda, e.g.:
for (int o = 0; o < 5; ++o)
{
int localO = o;
// now use "localO" in your lambda ...
}
Also, Random is not thread-safe. Using the same instance of Random simultaneously across multiple threads can corrupt its state and give you unexpected results.

I think you are making the assumption that the tasks are executed in the order they are created, and the TPL makes no such guarantees...
As for the 'o' parameter always printing as 5, that is because it is a local variable in the parent scope of the anonymous function, hence when the print is actually executed its value is 5 because the loop has completed (compare to 'i' being scoped within the anonymous function)

Related

Displaying parametres from a variable decision for each time the dvar == 1

I just get started on CPLEX so this is my problem:
I do have an issue I have a variable decision Y (patient allocated =1 if yes for the day i the hour h ) with three parameters (patient daytime ) and I want to display on a table on excel those results. one table with the Y==1 and their parameters beside this table.
if Ypih == Zpm= 1 (Zpm variable decision if the patient p is consulted from the doctor m ) then write on excel the patient p is registered to consult the doctor m on the day I at the hour h.
my problem is that i cannot display the parameters for their ranges for every instance of the loop .
so how to cross the pool solution to get the values of pih when Y==1==Z and display them
you can solve your problem as pointed below (assuming you're using the ILOG CPLEX Optimization Studio C++ library).
// solve your model
cplex.solve();
// now, we will verify all variables that are equal to 1
// first, we will loop through variables Y
for (int p_ = 0; p_ < maxP; p_++) {
for (int i_ = 0; i_ < maxI; i_++) {
for (int h_ = 0; h_ < maxH; h_++) {
// if Y_{pih} == 1
if (cplex.getValue(cplex.varY[p_][i_][h_]) == 1) {
// we will look if there is a variable Z == 1
for (int m_ = 0; m_ < maxM; m_++) {
if (cplex.getValue(cplex.varZ[p_][m_] == 1) {
// print or store your variables
}
}
}
}
}
}
After solving your model, you will need to verify which variables are equal to one. Thus, you can loop through all of your model variables and verify whether they are one or not, using the getValue CPLEX function.
See this link for a description regarding the CPLEX function.

List Count does not go to nextRow C++

The past few days, I've been desperately trying to fix an issue with my list count in C++.
This is my function that handles Count & Add new plr in list.
/*Iterator for players*/
list<Player*>::iterator itc;
list<Player*>PlayerCount;
int FindPosition(list<Player*>List, Player* plr)
{
int pos = 1;
for (itc = List.begin(); itc != List.end(); itc++, pos++)
{
if ((*itc) = plr)
break;
}
return pos;
}
What i'm trying to do is implement each time someone Queue in my list.
My output is currently showing this :
Player One Queue. Player Two Queue
it keep saying : Player in queue [1]
like there was no implementation for next row
How it Should be.
Player One : Player in queue [1]
Player Two : Player in Queue [2]
Thanks for helping !
As I mentioned in my comment above, the problem was the if ((*itc) = plr) was assigning plr to *itc instead of performing a comparison if ((*itc) == plr).
One friendly suggestion,
In FindPosition function, list<Player*>List is being passed by value which means that you are creating a copy of the whole list every time that you are calling the function. If that is the intended behavior then you can keep it as is otherwise you could rewrite it as follows:
// pass List by value
// int FindPosition(list<Player*>List, Player* plr)
// pass List by reference
int FindPosition(list<Player*>& List, Player* plr)
{
int pos = 1;
for (itc = List.begin(); itc != List.end(); itc++, pos++)
{
// changed from assigment (*itc) = plr
// to comparison (*itc) == plr
if ((*itc) == plr)
break;
}
return pos;
}

Renderscript and garbage collector

Recently I modified my code to store everything in the renderscript (before that I copied the data back and forth wasn't effective), but now the garbage collector is collecting garbage like crazy. (Still the app is preforming better this way.)
I can't figure out what needs to be collected, I use everything I don't create new arrays in the functions, which I call frequently. My only idea is that if I do this:
void __attribute__((kernel)) diffuseVelocityY(float in, uint32_t x, uint32_t y) {
velocityY_prev[x] = velocityY[x] + a*(velocityY_prev[x-1] + velocityY_prev[x+1] + velocityY_prev[x-(width)] + velocityY_prev[x+(width)])/(1+(4*a));
}
it creates a temperaly pointer for it because I'm using data from the same pointer that I want to update(I have no idea if this is the way it works). I tried to change it, so it puts the data in an empty pointer and after it finishes I copy the data to the right place. It seemd that it collected less garbage but there was still garbage collection and the preformance went down aswell.
I uploaded my code here if someone wants to look(the _befores are from before I modified the code).
I have no idea how to stop the garbage collection, I hope someone can help.
One of the methods:
void set_bnd_densiy_prev(int b){
for (int i = 1; i <= gridSizeY; i++) {
density_prev[IX(0, i)] = (b == 1 ? -density_prev[IX(1, i)] : density_prev[IX(1, i)]);
density_prev[IX(gridSizeX + 1, i)] = (b == 1 ? -density_prev[IX(gridSizeX, i)] : density_prev[IX(gridSizeX, i)]);
}
for (int i = 1; i <= gridSizeX; i++) {
density_prev[IX(i, 0)] = (b == 2 ? -density_prev[IX(i, 1)] : density_prev[IX(i, 1)]);
density_prev[IX(i, gridSizeY + 1)] = (b == 2 ? -density_prev[IX(i, gridSizeY)] : density_prev[IX(i, gridSizeY)]);
}
density_prev[IX(0 ,0 )] = 0.5f*(density_prev[IX(1,0 )]+density_prev[IX(0 ,1)]);
density_prev[IX(0 ,gridSizeY+1)] = 0.5f*(density_prev[IX(1,gridSizeY+1)]+density_prev[IX(0 ,gridSizeY )]);
density_prev[IX(gridSizeX+1,0 )] = 0.5f*(density_prev[IX(gridSizeX,0 )]+density_prev[IX(gridSizeX+1,1)]);
density_prev[IX(gridSizeX+1,gridSizeY+1)] = 0.5f*(density_prev[IX(gridSizeX,gridSizeY+1)]+density_prev[IX(gridSizeX+1,gridSizeY )]);
}
Code generated from it:
private final static int mExportFuncIdx_set_bnd_densiy_prev = 3;
public void invoke_set_bnd_densiy_prev(int b) {
FieldPacker set_bnd_densiy_prev_fp = new FieldPacker(4);
set_bnd_densiy_prev_fp.addI32(b);
invoke(mExportFuncIdx_set_bnd_densiy_prev, set_bnd_densiy_prev_fp);
}
The problem was with the function args because renderscript needs to create Fieldpackers to handle them. So if you have the same problem remove the function args then copy paste the function and modify the variables and call the different functions not pretty but it works.
(Thanks thebaron for your help)

C++\Cli Parallel::For with thread local variable - Error: too many arguments

Trying to implement my first Parallel::For loop with a tread local variable to sum results of the loop. My code is based on an example listed in "Visual C++ 2010, by W. Saumweber, D. Louis (German). Ch. 33, P.804).
I get stuck in the implementation with syntax errors in the Parallel::For call. The errors are as follows, from left to right: a) expected a type specifier, b) too many arguments for generic class "System::Func", c) pointer to member is not valid for a managed class, d) no operator "&" matches these operands.
In line with the book, I create a collection with data List<DataStructure^> numbers, which is subject to a calculation performed in method computeSumScore which is called by the Parallel::For routine in method sumScore. All results are summed in method finalizeSumScore using a lock.
Below I paste the full code of the .cpp part of the class, to show what I have. The data collection "numbers" may look a bit messy, but that's due to organical growth of the program and me learning as I go along.
// constructor
DataCollection::DataCollection(Form1^ f1) // takes parameter of type Form1 to give acces to variables on Form1
{
this->f1 = f1;
}
// initialize data set for parallel processing
void DataCollection::initNumbers(int cIdx)
{
DataStructure^ number;
numbers = gcnew List<DataStructure^>();
for (int i = 0; i < f1->myGenome->nGenes; i++)
{
number = gcnew DataStructure();
number->concentrationTF = f1->myOrgan->cellPtr[cIdx]->concTFA[i];
number->stringA->AddRange(f1->myGenome->cStruct[i]->gString->GetRange(0, f1->myGenome->cChars));
number->stringB->AddRange(f1->myGenome->cStruct[i]->pString);
if (f1->myGenome->cStruct[i]->inhibitFunc)
number->sign = -1;
else
number->sign = 1;
numbers->Add(number);
}
}
// parallel-for summation of scores
double DataCollection::sumScore()
{
Parallel::For<double>(0, numbers->Count, gcnew Func<double>(this, &GenomeV2::DataCollection::initSumScore),
gcnew Func<int, ParallelLoopState^, double, double>(this, &GenomeV2::DataCollection::computeSumScore),
gcnew Action<double>(this, &GenomeV2::DataCollection::finalizeSumScore));
return summation;
}
// returns start value
double DataCollection::initSumScore()
{
return 0.0;
}
// perform sequence alignment calculation
double DataCollection::computeSumScore(int k, ParallelLoopState^ status, double tempVal)
{
int nwScore;
if (numbers[k]->concentrationTF > 0)
{
nwScore = NeedlemanWunsch::computeGlobalSequenceAlignment(numbers[k]->stringA, numbers[k]->stringB);
tempVal = Mapping::getLinIntMapValue(nwScore); // mapped value (0-1)
tempVal = (double) numbers[k]->sign * tempVal * numbers[k]->concentrationTF;
}
else
tempVal = 0.0;
return tempVal;
}
// locked addition
void DataCollection::finalizeSumScore(double tempVal)
{
Object^ myLock = gcnew Object();
try
{
Monitor::Enter(myLock);
summation += tempVal;
}
finally
{
Monitor::Exit(myLock);
}
}
Once this problem is solved I need to ensure that the functions called (computeGlobalSequenceAlignment and getLinIntMapvalue) are thread safe and the program doesn't get stalled on multiple treads accessing the same (static) variables. But this needs to work first.
Hope you can help me out.
Hans Passant answered my question in the comments (include full method name, add comma). Yet I cannot mark my question as answered, so this answer is to close the question.

Java Concept Confusion : Objects and Primitive Types

I am really confused about this concept:
/* Example with primitive data type */
public class Example1 {
public static void main (String[] args){
int a = 1;
System.out.println("a is " + a);
myMethod( a );
System.out.println("a is " + a);
}
public static void myMethod(int b){
b = 3;
System.out.println("b is " + b);
}
}
OUTPUT:
a is 1
b is 3
a is 1
Why does "a" not change?How does this primitive variable CHANGE like for a FOR LOOP or a WHILE LOOP when int i is initialed to zero? Like this:
int i = 1;
while (i < = 3) {
System.out.println(i);
i *= 2;
}
OUTPUT:
1
2
Please let me know in detail, as I am really confused.i is a primitive type, why does it get updated, and why does not int a in the first program?
myMethod() is void, if it returned an int and you assigned a=myMethod(a) then it would change
int a = 1;
System.out.println("a is " + a);
a= myMethod(a); //where myMethod is changed to return b instead of void
System.out.println("a is " + a);
a is 1
b is 3
a is 3
"Why does "a" not change?"
Because primitive a inside of your myMethod is not the same a that you had in your void main. Treat it as completely another variable and that its value got copied into myMethod. This primitive`s lifecycle ends in the end of this method execution.
If you have C++ background then maybe this explanation might help:
When you pass primitive type arguments into method - you are passing
variables that are being copied. You passed value, not instance.
When you pass objects as arguments
into method - you are passing references to that object, but to be more precise: in java, a copy of reference value is being passed. It is like passing a copy of the address of the object to the method. If you modify this object inside this method, the modifications will be visible outside the method. If you =null or =new Obj it, it will affect the object only inside your method.

Resources