This blog is subject the DISCLAIMER below.

Friday, January 12, 2007

Threads Synchronization

In this post, we will talk about threads synchronization and how to achieve it specially when they use shared variables at this, synchronization is very vital and must to be obtained, for whom knew Process Synchronization and its solutions i.e. Semaphore, Monitors and so on. Try to read this article it will present a light solution without using Semaphore or Monitor classes let’s start our example, actually I’ve two processes, they currently share a variable called ‘aNumber’ each of which increments it, my main job here is to achieve synchronization more than writing the code itself .

public Multithreading()//constructor
{
ThreadStart firstThreadStart = new ThreadStart(FirstThread);
Thread firstThread = new Thread(firstThreadStart);
firstThread.Start();

ThreadStart secondThreadStart = new ThreadStart(SecondThread);
Thread secondThread = new Thread(secondThreadStart);
secondThread.Start();
}
public void FirstThread()
{
for (int i = 0; i < 100; i++)
{
aNumber++;
Console.Write(aNumber + " " );
}
}
public void SecondThread()
{
for (int i = 0; i < 100; i++)
{
aNumber++;
Console.Write(aNumber + " " );
}
}

Output is :
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 1 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 8 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 1 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 101 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 187 188 189 190 191 192 193 194 195 196 197 198 199 200

If you’ve a strong notice you will find no synchronization at all, and as loop increased, you will gain worse result.

So, we try to synchronize our two processes (FirstThread and SecondThread) there are two approches, first is to use lock and the second is to use volatile

Lets start with lock

private int aNumber;
private object synch;
public MultithreadingLock() //constructor
{
synch = new object();
ThreadStart firstThreadStart = new ThreadStart(FirstThread);
Thread firstThread = new Thread(firstThreadStart);
firstThread.Start();

ThreadStart secondThreadStart = new ThreadStart(SecondThread);
Thread secondThread = new Thread(secondThreadStart);
secondThread.Start();

}
public void FirstThread()
{
lock (synch)
{
for (int i = 0; i < 100; i++)
{
aNumber++;
Console.Write(aNumber + " ");
}
}
}
public void SecondThread()
{
lock (synch)
{
for (int i = 0; i < 100; i++)
{
aNumber++;
Console.Write(aNumber + " ");
}
}
}

Output is:
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 187 188 189 190 191 192 193 194 195 196 197 198 199 200

As you see we got the sychnoronization we want, but what about if I’ll create more than two functions, should I write lock (…) { } block in each, C# presents volatile keyword that indicates, field may be accessed and modified by more than one thread and this approche guarntee this field has up-to-date value at all times and I do not have to write lock block

public volatile int aNumber = 0;
public MultithreadingVolatile() //constructor
{
ThreadStart firstThreadStart = new ThreadStart(FirstThread);
Thread firstThread = new Thread(firstThreadStart);
firstThread.Start();

ThreadStart secondThreadStart = new ThreadStart(SecondThread);
Thread secondThread = new Thread(secondThreadStart);
secondThread.Start();

}
public void FirstThread()
{
for (int i = 0; i < 100; i++)
{
++aNumber;
Console.Write(aNumber + " ");
}
}
public void SecondThread()
{
for (int i = 0; i < 100; i++)
{
++aNumber;
Console.Write(aNumber + " ");
}
}

Output is:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 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 15 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 187 188 189 190 191 192 193 194 195 196 197 198 199 200

This keyword is useful when an external process (like the operating system or a thread in your application) can potentially modify the value of a field, and you need to ensure that you are reading the most current value.
Unfortunately, I cannot seem to get the C# compiler to generate code to demonstrate the differences between volatile and non-volatile memory reads, even with the optimization flag turned on. This is probably because of poor optimization in C#. [Said by: Marc Clifton on http://www.codeproject.com/csharp/modifierkeywords.asp ]

So, I see to get true synchronization you should use lock block

Yes, I mean to now write more than that to let you read more by yourself.
Your comments are welcome

4 comments:

Ramy Mahrous said...

Really sorry for post format but I do my best to make it pretty as you see :S

Anonymous said...

good blog and waiting for more usefull articles
hey nabil don't be lazy!

Mohammad Alaggan said...

who are you ?

Ramy Mahrous said...

It's Khaled Adel but when we upgrade to google or blogger 2 it converted some names to anonymous