What happens if a thread is in the critical section or entering the critical section?
I am trying to better understand a chapter and have been confused about what happens if a thread is in the critical section or is entering the critical section. May someone explain or give me an idea on the process of what the thread undergoes in such circumstances? Thank you.
operating-system thread-synchronization
add a comment |Â
I am trying to better understand a chapter and have been confused about what happens if a thread is in the critical section or is entering the critical section. May someone explain or give me an idea on the process of what the thread undergoes in such circumstances? Thank you.
operating-system thread-synchronization
add a comment |Â
I am trying to better understand a chapter and have been confused about what happens if a thread is in the critical section or is entering the critical section. May someone explain or give me an idea on the process of what the thread undergoes in such circumstances? Thank you.
operating-system thread-synchronization
I am trying to better understand a chapter and have been confused about what happens if a thread is in the critical section or is entering the critical section. May someone explain or give me an idea on the process of what the thread undergoes in such circumstances? Thank you.
operating-system thread-synchronization
operating-system thread-synchronization
asked Nov 11 at 0:06
justoneday
113
113
add a comment |Â
add a comment |Â
1 Answer
1
active
oldest
votes
For an example, let's assume that you have an array, and multiple threads that read and write to the array; and if different threads are reading and writing to the array at the same time they'd see inconsistent data and it'd cause problems. To prevent those problems you protect the array with some kind of lock - before doing anything with the array a thread acquires the array's lock, and when it's finished using the array the thread releases the array's lock.
For example:
acquire_array_lock();
/** Critical section (code that does something with the array) **/
release_array_lock();
There's nothing special about the code in the critical section. It does whatever it was designed to do (maybe sorting the array, maybe adding up all the numbers in the array, maybe displaying the array, etc) using code that's no different to code that you might use to do the same thing in a single-threaded system without locks.
The only special parts are the code to acquire and release the lock.
There are many types of locks (spinlocks, mutexes, semaphores), but they all have the same fundamental principle - when acquiring it you have something (e.g. a variable) to determine if a thread can/can't continue, then either (if the thread can't continue) some kind of waiting or (if the thread can continue) some kind of change to let others know they need to wait; and when releasing you have something to let others know they can stop waiting.
The main difference between different kinds of locks is the implementation details - what kind of data is used to determine if a thread can/can't continue, and how a thread waits.
For the simplest kind of lock (a spinlock) you might just have a single "yes/no" flag, a little bit like this (but not literally like this):
acquire_lock(void)
while(myLock == 0)
// do nothing then retry
myLock = 1;
release_lock(void)
myLock = 0;
However this won't work because two or more threads can see that myLock == 0
at the same time and think they can both continue (and then do the myLock = 1
after it's too late). To fix this you need assembly language or special language support for atomic operations (e.g. a special function for "test and set" or "compare and exchange").
The reason this is called a "spinlock" is that (if a thread needs to wait) it wastes CPU time continually checking ("spinning") to see if it can continue. Instead of doing this (to avoid wasting CPU time), a thread could tell a scheduler not to give it any CPU time until the lock is released; and this is how a mutex works.
thank you! But can the process holding the lock get context switched?
â justoneday
Nov 11 at 21:29
@justoneday: Whether a task holding a lock can get context switched depends on the environment. For normal tasks (threads, processes) on most operating systems a task can be context switched while holding a lock (otherwise there's a risk of malicious code deliberately acquiring a lock and never releasing it to hog all of the CPU time). For kernel code using spinlocks, typically context switches (and possibly IRQs too) are disabled to minimise the time that other CPUs will spend spinning.
â Brendan
Nov 12 at 3:57
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
For an example, let's assume that you have an array, and multiple threads that read and write to the array; and if different threads are reading and writing to the array at the same time they'd see inconsistent data and it'd cause problems. To prevent those problems you protect the array with some kind of lock - before doing anything with the array a thread acquires the array's lock, and when it's finished using the array the thread releases the array's lock.
For example:
acquire_array_lock();
/** Critical section (code that does something with the array) **/
release_array_lock();
There's nothing special about the code in the critical section. It does whatever it was designed to do (maybe sorting the array, maybe adding up all the numbers in the array, maybe displaying the array, etc) using code that's no different to code that you might use to do the same thing in a single-threaded system without locks.
The only special parts are the code to acquire and release the lock.
There are many types of locks (spinlocks, mutexes, semaphores), but they all have the same fundamental principle - when acquiring it you have something (e.g. a variable) to determine if a thread can/can't continue, then either (if the thread can't continue) some kind of waiting or (if the thread can continue) some kind of change to let others know they need to wait; and when releasing you have something to let others know they can stop waiting.
The main difference between different kinds of locks is the implementation details - what kind of data is used to determine if a thread can/can't continue, and how a thread waits.
For the simplest kind of lock (a spinlock) you might just have a single "yes/no" flag, a little bit like this (but not literally like this):
acquire_lock(void)
while(myLock == 0)
// do nothing then retry
myLock = 1;
release_lock(void)
myLock = 0;
However this won't work because two or more threads can see that myLock == 0
at the same time and think they can both continue (and then do the myLock = 1
after it's too late). To fix this you need assembly language or special language support for atomic operations (e.g. a special function for "test and set" or "compare and exchange").
The reason this is called a "spinlock" is that (if a thread needs to wait) it wastes CPU time continually checking ("spinning") to see if it can continue. Instead of doing this (to avoid wasting CPU time), a thread could tell a scheduler not to give it any CPU time until the lock is released; and this is how a mutex works.
thank you! But can the process holding the lock get context switched?
â justoneday
Nov 11 at 21:29
@justoneday: Whether a task holding a lock can get context switched depends on the environment. For normal tasks (threads, processes) on most operating systems a task can be context switched while holding a lock (otherwise there's a risk of malicious code deliberately acquiring a lock and never releasing it to hog all of the CPU time). For kernel code using spinlocks, typically context switches (and possibly IRQs too) are disabled to minimise the time that other CPUs will spend spinning.
â Brendan
Nov 12 at 3:57
add a comment |Â
For an example, let's assume that you have an array, and multiple threads that read and write to the array; and if different threads are reading and writing to the array at the same time they'd see inconsistent data and it'd cause problems. To prevent those problems you protect the array with some kind of lock - before doing anything with the array a thread acquires the array's lock, and when it's finished using the array the thread releases the array's lock.
For example:
acquire_array_lock();
/** Critical section (code that does something with the array) **/
release_array_lock();
There's nothing special about the code in the critical section. It does whatever it was designed to do (maybe sorting the array, maybe adding up all the numbers in the array, maybe displaying the array, etc) using code that's no different to code that you might use to do the same thing in a single-threaded system without locks.
The only special parts are the code to acquire and release the lock.
There are many types of locks (spinlocks, mutexes, semaphores), but they all have the same fundamental principle - when acquiring it you have something (e.g. a variable) to determine if a thread can/can't continue, then either (if the thread can't continue) some kind of waiting or (if the thread can continue) some kind of change to let others know they need to wait; and when releasing you have something to let others know they can stop waiting.
The main difference between different kinds of locks is the implementation details - what kind of data is used to determine if a thread can/can't continue, and how a thread waits.
For the simplest kind of lock (a spinlock) you might just have a single "yes/no" flag, a little bit like this (but not literally like this):
acquire_lock(void)
while(myLock == 0)
// do nothing then retry
myLock = 1;
release_lock(void)
myLock = 0;
However this won't work because two or more threads can see that myLock == 0
at the same time and think they can both continue (and then do the myLock = 1
after it's too late). To fix this you need assembly language or special language support for atomic operations (e.g. a special function for "test and set" or "compare and exchange").
The reason this is called a "spinlock" is that (if a thread needs to wait) it wastes CPU time continually checking ("spinning") to see if it can continue. Instead of doing this (to avoid wasting CPU time), a thread could tell a scheduler not to give it any CPU time until the lock is released; and this is how a mutex works.
thank you! But can the process holding the lock get context switched?
â justoneday
Nov 11 at 21:29
@justoneday: Whether a task holding a lock can get context switched depends on the environment. For normal tasks (threads, processes) on most operating systems a task can be context switched while holding a lock (otherwise there's a risk of malicious code deliberately acquiring a lock and never releasing it to hog all of the CPU time). For kernel code using spinlocks, typically context switches (and possibly IRQs too) are disabled to minimise the time that other CPUs will spend spinning.
â Brendan
Nov 12 at 3:57
add a comment |Â
For an example, let's assume that you have an array, and multiple threads that read and write to the array; and if different threads are reading and writing to the array at the same time they'd see inconsistent data and it'd cause problems. To prevent those problems you protect the array with some kind of lock - before doing anything with the array a thread acquires the array's lock, and when it's finished using the array the thread releases the array's lock.
For example:
acquire_array_lock();
/** Critical section (code that does something with the array) **/
release_array_lock();
There's nothing special about the code in the critical section. It does whatever it was designed to do (maybe sorting the array, maybe adding up all the numbers in the array, maybe displaying the array, etc) using code that's no different to code that you might use to do the same thing in a single-threaded system without locks.
The only special parts are the code to acquire and release the lock.
There are many types of locks (spinlocks, mutexes, semaphores), but they all have the same fundamental principle - when acquiring it you have something (e.g. a variable) to determine if a thread can/can't continue, then either (if the thread can't continue) some kind of waiting or (if the thread can continue) some kind of change to let others know they need to wait; and when releasing you have something to let others know they can stop waiting.
The main difference between different kinds of locks is the implementation details - what kind of data is used to determine if a thread can/can't continue, and how a thread waits.
For the simplest kind of lock (a spinlock) you might just have a single "yes/no" flag, a little bit like this (but not literally like this):
acquire_lock(void)
while(myLock == 0)
// do nothing then retry
myLock = 1;
release_lock(void)
myLock = 0;
However this won't work because two or more threads can see that myLock == 0
at the same time and think they can both continue (and then do the myLock = 1
after it's too late). To fix this you need assembly language or special language support for atomic operations (e.g. a special function for "test and set" or "compare and exchange").
The reason this is called a "spinlock" is that (if a thread needs to wait) it wastes CPU time continually checking ("spinning") to see if it can continue. Instead of doing this (to avoid wasting CPU time), a thread could tell a scheduler not to give it any CPU time until the lock is released; and this is how a mutex works.
For an example, let's assume that you have an array, and multiple threads that read and write to the array; and if different threads are reading and writing to the array at the same time they'd see inconsistent data and it'd cause problems. To prevent those problems you protect the array with some kind of lock - before doing anything with the array a thread acquires the array's lock, and when it's finished using the array the thread releases the array's lock.
For example:
acquire_array_lock();
/** Critical section (code that does something with the array) **/
release_array_lock();
There's nothing special about the code in the critical section. It does whatever it was designed to do (maybe sorting the array, maybe adding up all the numbers in the array, maybe displaying the array, etc) using code that's no different to code that you might use to do the same thing in a single-threaded system without locks.
The only special parts are the code to acquire and release the lock.
There are many types of locks (spinlocks, mutexes, semaphores), but they all have the same fundamental principle - when acquiring it you have something (e.g. a variable) to determine if a thread can/can't continue, then either (if the thread can't continue) some kind of waiting or (if the thread can continue) some kind of change to let others know they need to wait; and when releasing you have something to let others know they can stop waiting.
The main difference between different kinds of locks is the implementation details - what kind of data is used to determine if a thread can/can't continue, and how a thread waits.
For the simplest kind of lock (a spinlock) you might just have a single "yes/no" flag, a little bit like this (but not literally like this):
acquire_lock(void)
while(myLock == 0)
// do nothing then retry
myLock = 1;
release_lock(void)
myLock = 0;
However this won't work because two or more threads can see that myLock == 0
at the same time and think they can both continue (and then do the myLock = 1
after it's too late). To fix this you need assembly language or special language support for atomic operations (e.g. a special function for "test and set" or "compare and exchange").
The reason this is called a "spinlock" is that (if a thread needs to wait) it wastes CPU time continually checking ("spinning") to see if it can continue. Instead of doing this (to avoid wasting CPU time), a thread could tell a scheduler not to give it any CPU time until the lock is released; and this is how a mutex works.
answered Nov 11 at 4:10
Brendan
12.2k1230
12.2k1230
thank you! But can the process holding the lock get context switched?
â justoneday
Nov 11 at 21:29
@justoneday: Whether a task holding a lock can get context switched depends on the environment. For normal tasks (threads, processes) on most operating systems a task can be context switched while holding a lock (otherwise there's a risk of malicious code deliberately acquiring a lock and never releasing it to hog all of the CPU time). For kernel code using spinlocks, typically context switches (and possibly IRQs too) are disabled to minimise the time that other CPUs will spend spinning.
â Brendan
Nov 12 at 3:57
add a comment |Â
thank you! But can the process holding the lock get context switched?
â justoneday
Nov 11 at 21:29
@justoneday: Whether a task holding a lock can get context switched depends on the environment. For normal tasks (threads, processes) on most operating systems a task can be context switched while holding a lock (otherwise there's a risk of malicious code deliberately acquiring a lock and never releasing it to hog all of the CPU time). For kernel code using spinlocks, typically context switches (and possibly IRQs too) are disabled to minimise the time that other CPUs will spend spinning.
â Brendan
Nov 12 at 3:57
thank you! But can the process holding the lock get context switched?
â justoneday
Nov 11 at 21:29
thank you! But can the process holding the lock get context switched?
â justoneday
Nov 11 at 21:29
@justoneday: Whether a task holding a lock can get context switched depends on the environment. For normal tasks (threads, processes) on most operating systems a task can be context switched while holding a lock (otherwise there's a risk of malicious code deliberately acquiring a lock and never releasing it to hog all of the CPU time). For kernel code using spinlocks, typically context switches (and possibly IRQs too) are disabled to minimise the time that other CPUs will spend spinning.
â Brendan
Nov 12 at 3:57
@justoneday: Whether a task holding a lock can get context switched depends on the environment. For normal tasks (threads, processes) on most operating systems a task can be context switched while holding a lock (otherwise there's a risk of malicious code deliberately acquiring a lock and never releasing it to hog all of the CPU time). For kernel code using spinlocks, typically context switches (and possibly IRQs too) are disabled to minimise the time that other CPUs will spend spinning.
â Brendan
Nov 12 at 3:57
add a comment |Â
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid â¦
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid â¦
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53244644%2fwhat-happens-if-a-thread-is-in-the-critical-section-or-entering-the-critical-sec%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown