Is there a C++ design pattern that implements a mechanism or mutex that controls the amount of time a thread...
I am looking for a way to guarantee that any time a thread locks a specific resource, it is forced to release that resource after a specific period of time (if it has not already released it).
I envision this is how it could be used:
{
std::lock_guard<std::TimeLimitedMutex> lock(this->myTimeLimitedMutex, timeout);
try {
// perform some operation with the resource that myTimeLimitedMutex guards.
}
catch (MutexTimeoutException ex) {
// perform cleanup
}
}
I see that there is a timed_mutex that lets the program timeout if a lock cannot be acquired. I need the timeout to occur after the lock is acquired.
c++ mutex deadlock
|
show 8 more comments
I am looking for a way to guarantee that any time a thread locks a specific resource, it is forced to release that resource after a specific period of time (if it has not already released it).
I envision this is how it could be used:
{
std::lock_guard<std::TimeLimitedMutex> lock(this->myTimeLimitedMutex, timeout);
try {
// perform some operation with the resource that myTimeLimitedMutex guards.
}
catch (MutexTimeoutException ex) {
// perform cleanup
}
}
I see that there is a timed_mutex that lets the program timeout if a lock cannot be acquired. I need the timeout to occur after the lock is acquired.
c++ mutex deadlock
5
AFAIK only the opposite is provided. I believe you need to write your own.
– NathanOliver
5 hours ago
4
The tricky part will be deciding how the thread that currently owns the lock will be notified or otherwise realize that it's lock now belongs to someone else.
– François Andrieux
5 hours ago
3
Isn't that a bit against the principle of "owning" a resource? Also, implementing a timeout when you have a lock might get awful in some cases performance-wise. Imagine a timeout of of 500ms but it would have took 505ms to complete all the work. What happens then?
– AlexG
5 hours ago
3
This sounds tricky. It may be that you will have to put regular checks in the worker thread whether or not to terminate. I mean what if you only partially modified the state of the resource leaving it in an unpredictable condition for the preempting thread to take over from?
– Galik
5 hours ago
2
The thread that owns the lock periodically checks to see how long it has held the lock, and if it exceeds the threshold it relinquishes the lock and does whatever cleanup required. The concept is similar to cooperative multitasking, in contrast to the much more prevalent preemptive multitasking. Note: there's a reason preemptive multitasking is more prevalent, even though it is less efficient than cooperative multitasking.
– Eljay
4 hours ago
|
show 8 more comments
I am looking for a way to guarantee that any time a thread locks a specific resource, it is forced to release that resource after a specific period of time (if it has not already released it).
I envision this is how it could be used:
{
std::lock_guard<std::TimeLimitedMutex> lock(this->myTimeLimitedMutex, timeout);
try {
// perform some operation with the resource that myTimeLimitedMutex guards.
}
catch (MutexTimeoutException ex) {
// perform cleanup
}
}
I see that there is a timed_mutex that lets the program timeout if a lock cannot be acquired. I need the timeout to occur after the lock is acquired.
c++ mutex deadlock
I am looking for a way to guarantee that any time a thread locks a specific resource, it is forced to release that resource after a specific period of time (if it has not already released it).
I envision this is how it could be used:
{
std::lock_guard<std::TimeLimitedMutex> lock(this->myTimeLimitedMutex, timeout);
try {
// perform some operation with the resource that myTimeLimitedMutex guards.
}
catch (MutexTimeoutException ex) {
// perform cleanup
}
}
I see that there is a timed_mutex that lets the program timeout if a lock cannot be acquired. I need the timeout to occur after the lock is acquired.
c++ mutex deadlock
c++ mutex deadlock
asked 5 hours ago
Jay ElstonJay Elston
1,51211533
1,51211533
5
AFAIK only the opposite is provided. I believe you need to write your own.
– NathanOliver
5 hours ago
4
The tricky part will be deciding how the thread that currently owns the lock will be notified or otherwise realize that it's lock now belongs to someone else.
– François Andrieux
5 hours ago
3
Isn't that a bit against the principle of "owning" a resource? Also, implementing a timeout when you have a lock might get awful in some cases performance-wise. Imagine a timeout of of 500ms but it would have took 505ms to complete all the work. What happens then?
– AlexG
5 hours ago
3
This sounds tricky. It may be that you will have to put regular checks in the worker thread whether or not to terminate. I mean what if you only partially modified the state of the resource leaving it in an unpredictable condition for the preempting thread to take over from?
– Galik
5 hours ago
2
The thread that owns the lock periodically checks to see how long it has held the lock, and if it exceeds the threshold it relinquishes the lock and does whatever cleanup required. The concept is similar to cooperative multitasking, in contrast to the much more prevalent preemptive multitasking. Note: there's a reason preemptive multitasking is more prevalent, even though it is less efficient than cooperative multitasking.
– Eljay
4 hours ago
|
show 8 more comments
5
AFAIK only the opposite is provided. I believe you need to write your own.
– NathanOliver
5 hours ago
4
The tricky part will be deciding how the thread that currently owns the lock will be notified or otherwise realize that it's lock now belongs to someone else.
– François Andrieux
5 hours ago
3
Isn't that a bit against the principle of "owning" a resource? Also, implementing a timeout when you have a lock might get awful in some cases performance-wise. Imagine a timeout of of 500ms but it would have took 505ms to complete all the work. What happens then?
– AlexG
5 hours ago
3
This sounds tricky. It may be that you will have to put regular checks in the worker thread whether or not to terminate. I mean what if you only partially modified the state of the resource leaving it in an unpredictable condition for the preempting thread to take over from?
– Galik
5 hours ago
2
The thread that owns the lock periodically checks to see how long it has held the lock, and if it exceeds the threshold it relinquishes the lock and does whatever cleanup required. The concept is similar to cooperative multitasking, in contrast to the much more prevalent preemptive multitasking. Note: there's a reason preemptive multitasking is more prevalent, even though it is less efficient than cooperative multitasking.
– Eljay
4 hours ago
5
5
AFAIK only the opposite is provided. I believe you need to write your own.
– NathanOliver
5 hours ago
AFAIK only the opposite is provided. I believe you need to write your own.
– NathanOliver
5 hours ago
4
4
The tricky part will be deciding how the thread that currently owns the lock will be notified or otherwise realize that it's lock now belongs to someone else.
– François Andrieux
5 hours ago
The tricky part will be deciding how the thread that currently owns the lock will be notified or otherwise realize that it's lock now belongs to someone else.
– François Andrieux
5 hours ago
3
3
Isn't that a bit against the principle of "owning" a resource? Also, implementing a timeout when you have a lock might get awful in some cases performance-wise. Imagine a timeout of of 500ms but it would have took 505ms to complete all the work. What happens then?
– AlexG
5 hours ago
Isn't that a bit against the principle of "owning" a resource? Also, implementing a timeout when you have a lock might get awful in some cases performance-wise. Imagine a timeout of of 500ms but it would have took 505ms to complete all the work. What happens then?
– AlexG
5 hours ago
3
3
This sounds tricky. It may be that you will have to put regular checks in the worker thread whether or not to terminate. I mean what if you only partially modified the state of the resource leaving it in an unpredictable condition for the preempting thread to take over from?
– Galik
5 hours ago
This sounds tricky. It may be that you will have to put regular checks in the worker thread whether or not to terminate. I mean what if you only partially modified the state of the resource leaving it in an unpredictable condition for the preempting thread to take over from?
– Galik
5 hours ago
2
2
The thread that owns the lock periodically checks to see how long it has held the lock, and if it exceeds the threshold it relinquishes the lock and does whatever cleanup required. The concept is similar to cooperative multitasking, in contrast to the much more prevalent preemptive multitasking. Note: there's a reason preemptive multitasking is more prevalent, even though it is less efficient than cooperative multitasking.
– Eljay
4 hours ago
The thread that owns the lock periodically checks to see how long it has held the lock, and if it exceeds the threshold it relinquishes the lock and does whatever cleanup required. The concept is similar to cooperative multitasking, in contrast to the much more prevalent preemptive multitasking. Note: there's a reason preemptive multitasking is more prevalent, even though it is less efficient than cooperative multitasking.
– Eljay
4 hours ago
|
show 8 more comments
4 Answers
4
active
oldest
votes
This can't work, and it will never work. In other words, this can never be made. It goes against all concept of ownership and atomic transactions. Because when thread acquires the lock and implements two transactions in a row, it expects them to become atomically visible to outside word. In this scenario, it would be very possible that the transaction will be torn - first part of it will be performed, but the second will be not.
What's worse is that since the lock will be forcefully removed, the part-executed transaction will become visible to outside word, before the interrupted thread has any chance to roll-back.
This idea goes contrary to all school of multi-threaded thinking.
1
Some mechanisms for updating shared resources, such as compare-and-swap, can handle "rollbacks" without the interrupted thread having to do anything. Using locks for arbitration may offer better performance than having threads attempt updates which end up failing, but forcibly stealing an object from the thread that's updating it would merely hurt performance, not correctness.
– supercat
54 mins ago
add a comment |
I support SergeyAs answer. Releasing a locked mutex after a timeout is a bad idea and cannot work. Mutex stands for mutual exclusion and this is a rock-hard contract which cannot be violated.
But you can do what you want:
Problem: You want to be able to specify a time T so that the thread never locks any mutex longer than time T.
Solution: Never lock the mutex for longer than T, but write your code so that you lock the mutex only for the absolutely necessary operations. It is always possible to give such a time T (modulo the uncertainties and limits given my a multitasking and multiuser operating system of course).
For example: Never do file I/O inside a locked section. Never sort a list while a mutex is locked. Never call a system call while a mutex is locked. There are exceptions to these rules, but the general guideline is: Make you code slightly less optimal (e.g. do some redundant copying inside the critical section) to make the critical section as short as possible. This is good multithreading programming.
add a comment |
Such an approach cannot be enforced because the holder of the mutex needs the opportunity to clean up anything which is left in an invalid state part way through the transaction. This can take an unknown arbitrary amount of time.
The typical approach is to release the lock when doing long tasks, and re-aquire it as needed. You have to manage this yourself as everyone will have a slightly different approach.
The only situation I know of where this sort of thing is accepted practice is at the kernel level, especially with respect to microcontrollers (which either have no kernel, or are all kernel, depending on who you ask). You can set an interrupt which modifies the call stack, so that when it is triggered it unwinds the particular operations you are interested in.
add a comment |
You can't do that with only C++.
If you are using a Posix system, it can be done.
You'll have to trigger a SIGALARM signal that's only unmasked for the thread that'll timeout. In the signal handler, you'll have to set a flag and use longjmp
to return to the thread code.
In the thread code, on the setjmp
position, you can only be called if the signal was triggered, thus you can throw the Timeout
exception.
Please see this answer for how to do that.
Also, on linux, it seems you can directly throw from the signal handler (so no longjmp/setjmp here).
BTW, if I were you, I would code the opposite. Think about it: You want to tell a thread "hey, you're taking too long, so let's throw away all the (long) work you've done so far so I can make progress".
Ideally, you should have your long thread be more cooperative, doing something like "I've done A of a ABCD task, let's release the mutex so other can progress on A. Then let's check if I can take it again to do B and so on."
You probably want to be more fine grained (have more mutex on smaller objects, but make sure you're locking in the same order) or use RW locks (so that other threads can use the objects if you're not modifying them), etc...
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
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%2f54598455%2fis-there-a-c-design-pattern-that-implements-a-mechanism-or-mutex-that-controls%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
This can't work, and it will never work. In other words, this can never be made. It goes against all concept of ownership and atomic transactions. Because when thread acquires the lock and implements two transactions in a row, it expects them to become atomically visible to outside word. In this scenario, it would be very possible that the transaction will be torn - first part of it will be performed, but the second will be not.
What's worse is that since the lock will be forcefully removed, the part-executed transaction will become visible to outside word, before the interrupted thread has any chance to roll-back.
This idea goes contrary to all school of multi-threaded thinking.
1
Some mechanisms for updating shared resources, such as compare-and-swap, can handle "rollbacks" without the interrupted thread having to do anything. Using locks for arbitration may offer better performance than having threads attempt updates which end up failing, but forcibly stealing an object from the thread that's updating it would merely hurt performance, not correctness.
– supercat
54 mins ago
add a comment |
This can't work, and it will never work. In other words, this can never be made. It goes against all concept of ownership and atomic transactions. Because when thread acquires the lock and implements two transactions in a row, it expects them to become atomically visible to outside word. In this scenario, it would be very possible that the transaction will be torn - first part of it will be performed, but the second will be not.
What's worse is that since the lock will be forcefully removed, the part-executed transaction will become visible to outside word, before the interrupted thread has any chance to roll-back.
This idea goes contrary to all school of multi-threaded thinking.
1
Some mechanisms for updating shared resources, such as compare-and-swap, can handle "rollbacks" without the interrupted thread having to do anything. Using locks for arbitration may offer better performance than having threads attempt updates which end up failing, but forcibly stealing an object from the thread that's updating it would merely hurt performance, not correctness.
– supercat
54 mins ago
add a comment |
This can't work, and it will never work. In other words, this can never be made. It goes against all concept of ownership and atomic transactions. Because when thread acquires the lock and implements two transactions in a row, it expects them to become atomically visible to outside word. In this scenario, it would be very possible that the transaction will be torn - first part of it will be performed, but the second will be not.
What's worse is that since the lock will be forcefully removed, the part-executed transaction will become visible to outside word, before the interrupted thread has any chance to roll-back.
This idea goes contrary to all school of multi-threaded thinking.
This can't work, and it will never work. In other words, this can never be made. It goes against all concept of ownership and atomic transactions. Because when thread acquires the lock and implements two transactions in a row, it expects them to become atomically visible to outside word. In this scenario, it would be very possible that the transaction will be torn - first part of it will be performed, but the second will be not.
What's worse is that since the lock will be forcefully removed, the part-executed transaction will become visible to outside word, before the interrupted thread has any chance to roll-back.
This idea goes contrary to all school of multi-threaded thinking.
answered 5 hours ago
SergeyASergeyA
42.8k53786
42.8k53786
1
Some mechanisms for updating shared resources, such as compare-and-swap, can handle "rollbacks" without the interrupted thread having to do anything. Using locks for arbitration may offer better performance than having threads attempt updates which end up failing, but forcibly stealing an object from the thread that's updating it would merely hurt performance, not correctness.
– supercat
54 mins ago
add a comment |
1
Some mechanisms for updating shared resources, such as compare-and-swap, can handle "rollbacks" without the interrupted thread having to do anything. Using locks for arbitration may offer better performance than having threads attempt updates which end up failing, but forcibly stealing an object from the thread that's updating it would merely hurt performance, not correctness.
– supercat
54 mins ago
1
1
Some mechanisms for updating shared resources, such as compare-and-swap, can handle "rollbacks" without the interrupted thread having to do anything. Using locks for arbitration may offer better performance than having threads attempt updates which end up failing, but forcibly stealing an object from the thread that's updating it would merely hurt performance, not correctness.
– supercat
54 mins ago
Some mechanisms for updating shared resources, such as compare-and-swap, can handle "rollbacks" without the interrupted thread having to do anything. Using locks for arbitration may offer better performance than having threads attempt updates which end up failing, but forcibly stealing an object from the thread that's updating it would merely hurt performance, not correctness.
– supercat
54 mins ago
add a comment |
I support SergeyAs answer. Releasing a locked mutex after a timeout is a bad idea and cannot work. Mutex stands for mutual exclusion and this is a rock-hard contract which cannot be violated.
But you can do what you want:
Problem: You want to be able to specify a time T so that the thread never locks any mutex longer than time T.
Solution: Never lock the mutex for longer than T, but write your code so that you lock the mutex only for the absolutely necessary operations. It is always possible to give such a time T (modulo the uncertainties and limits given my a multitasking and multiuser operating system of course).
For example: Never do file I/O inside a locked section. Never sort a list while a mutex is locked. Never call a system call while a mutex is locked. There are exceptions to these rules, but the general guideline is: Make you code slightly less optimal (e.g. do some redundant copying inside the critical section) to make the critical section as short as possible. This is good multithreading programming.
add a comment |
I support SergeyAs answer. Releasing a locked mutex after a timeout is a bad idea and cannot work. Mutex stands for mutual exclusion and this is a rock-hard contract which cannot be violated.
But you can do what you want:
Problem: You want to be able to specify a time T so that the thread never locks any mutex longer than time T.
Solution: Never lock the mutex for longer than T, but write your code so that you lock the mutex only for the absolutely necessary operations. It is always possible to give such a time T (modulo the uncertainties and limits given my a multitasking and multiuser operating system of course).
For example: Never do file I/O inside a locked section. Never sort a list while a mutex is locked. Never call a system call while a mutex is locked. There are exceptions to these rules, but the general guideline is: Make you code slightly less optimal (e.g. do some redundant copying inside the critical section) to make the critical section as short as possible. This is good multithreading programming.
add a comment |
I support SergeyAs answer. Releasing a locked mutex after a timeout is a bad idea and cannot work. Mutex stands for mutual exclusion and this is a rock-hard contract which cannot be violated.
But you can do what you want:
Problem: You want to be able to specify a time T so that the thread never locks any mutex longer than time T.
Solution: Never lock the mutex for longer than T, but write your code so that you lock the mutex only for the absolutely necessary operations. It is always possible to give such a time T (modulo the uncertainties and limits given my a multitasking and multiuser operating system of course).
For example: Never do file I/O inside a locked section. Never sort a list while a mutex is locked. Never call a system call while a mutex is locked. There are exceptions to these rules, but the general guideline is: Make you code slightly less optimal (e.g. do some redundant copying inside the critical section) to make the critical section as short as possible. This is good multithreading programming.
I support SergeyAs answer. Releasing a locked mutex after a timeout is a bad idea and cannot work. Mutex stands for mutual exclusion and this is a rock-hard contract which cannot be violated.
But you can do what you want:
Problem: You want to be able to specify a time T so that the thread never locks any mutex longer than time T.
Solution: Never lock the mutex for longer than T, but write your code so that you lock the mutex only for the absolutely necessary operations. It is always possible to give such a time T (modulo the uncertainties and limits given my a multitasking and multiuser operating system of course).
For example: Never do file I/O inside a locked section. Never sort a list while a mutex is locked. Never call a system call while a mutex is locked. There are exceptions to these rules, but the general guideline is: Make you code slightly less optimal (e.g. do some redundant copying inside the critical section) to make the critical section as short as possible. This is good multithreading programming.
edited 4 hours ago
answered 5 hours ago
Johannes OvermannJohannes Overmann
2,7081221
2,7081221
add a comment |
add a comment |
Such an approach cannot be enforced because the holder of the mutex needs the opportunity to clean up anything which is left in an invalid state part way through the transaction. This can take an unknown arbitrary amount of time.
The typical approach is to release the lock when doing long tasks, and re-aquire it as needed. You have to manage this yourself as everyone will have a slightly different approach.
The only situation I know of where this sort of thing is accepted practice is at the kernel level, especially with respect to microcontrollers (which either have no kernel, or are all kernel, depending on who you ask). You can set an interrupt which modifies the call stack, so that when it is triggered it unwinds the particular operations you are interested in.
add a comment |
Such an approach cannot be enforced because the holder of the mutex needs the opportunity to clean up anything which is left in an invalid state part way through the transaction. This can take an unknown arbitrary amount of time.
The typical approach is to release the lock when doing long tasks, and re-aquire it as needed. You have to manage this yourself as everyone will have a slightly different approach.
The only situation I know of where this sort of thing is accepted practice is at the kernel level, especially with respect to microcontrollers (which either have no kernel, or are all kernel, depending on who you ask). You can set an interrupt which modifies the call stack, so that when it is triggered it unwinds the particular operations you are interested in.
add a comment |
Such an approach cannot be enforced because the holder of the mutex needs the opportunity to clean up anything which is left in an invalid state part way through the transaction. This can take an unknown arbitrary amount of time.
The typical approach is to release the lock when doing long tasks, and re-aquire it as needed. You have to manage this yourself as everyone will have a slightly different approach.
The only situation I know of where this sort of thing is accepted practice is at the kernel level, especially with respect to microcontrollers (which either have no kernel, or are all kernel, depending on who you ask). You can set an interrupt which modifies the call stack, so that when it is triggered it unwinds the particular operations you are interested in.
Such an approach cannot be enforced because the holder of the mutex needs the opportunity to clean up anything which is left in an invalid state part way through the transaction. This can take an unknown arbitrary amount of time.
The typical approach is to release the lock when doing long tasks, and re-aquire it as needed. You have to manage this yourself as everyone will have a slightly different approach.
The only situation I know of where this sort of thing is accepted practice is at the kernel level, especially with respect to microcontrollers (which either have no kernel, or are all kernel, depending on who you ask). You can set an interrupt which modifies the call stack, so that when it is triggered it unwinds the particular operations you are interested in.
answered 1 hour ago
Cort AmmonCort Ammon
5,6871633
5,6871633
add a comment |
add a comment |
You can't do that with only C++.
If you are using a Posix system, it can be done.
You'll have to trigger a SIGALARM signal that's only unmasked for the thread that'll timeout. In the signal handler, you'll have to set a flag and use longjmp
to return to the thread code.
In the thread code, on the setjmp
position, you can only be called if the signal was triggered, thus you can throw the Timeout
exception.
Please see this answer for how to do that.
Also, on linux, it seems you can directly throw from the signal handler (so no longjmp/setjmp here).
BTW, if I were you, I would code the opposite. Think about it: You want to tell a thread "hey, you're taking too long, so let's throw away all the (long) work you've done so far so I can make progress".
Ideally, you should have your long thread be more cooperative, doing something like "I've done A of a ABCD task, let's release the mutex so other can progress on A. Then let's check if I can take it again to do B and so on."
You probably want to be more fine grained (have more mutex on smaller objects, but make sure you're locking in the same order) or use RW locks (so that other threads can use the objects if you're not modifying them), etc...
add a comment |
You can't do that with only C++.
If you are using a Posix system, it can be done.
You'll have to trigger a SIGALARM signal that's only unmasked for the thread that'll timeout. In the signal handler, you'll have to set a flag and use longjmp
to return to the thread code.
In the thread code, on the setjmp
position, you can only be called if the signal was triggered, thus you can throw the Timeout
exception.
Please see this answer for how to do that.
Also, on linux, it seems you can directly throw from the signal handler (so no longjmp/setjmp here).
BTW, if I were you, I would code the opposite. Think about it: You want to tell a thread "hey, you're taking too long, so let's throw away all the (long) work you've done so far so I can make progress".
Ideally, you should have your long thread be more cooperative, doing something like "I've done A of a ABCD task, let's release the mutex so other can progress on A. Then let's check if I can take it again to do B and so on."
You probably want to be more fine grained (have more mutex on smaller objects, but make sure you're locking in the same order) or use RW locks (so that other threads can use the objects if you're not modifying them), etc...
add a comment |
You can't do that with only C++.
If you are using a Posix system, it can be done.
You'll have to trigger a SIGALARM signal that's only unmasked for the thread that'll timeout. In the signal handler, you'll have to set a flag and use longjmp
to return to the thread code.
In the thread code, on the setjmp
position, you can only be called if the signal was triggered, thus you can throw the Timeout
exception.
Please see this answer for how to do that.
Also, on linux, it seems you can directly throw from the signal handler (so no longjmp/setjmp here).
BTW, if I were you, I would code the opposite. Think about it: You want to tell a thread "hey, you're taking too long, so let's throw away all the (long) work you've done so far so I can make progress".
Ideally, you should have your long thread be more cooperative, doing something like "I've done A of a ABCD task, let's release the mutex so other can progress on A. Then let's check if I can take it again to do B and so on."
You probably want to be more fine grained (have more mutex on smaller objects, but make sure you're locking in the same order) or use RW locks (so that other threads can use the objects if you're not modifying them), etc...
You can't do that with only C++.
If you are using a Posix system, it can be done.
You'll have to trigger a SIGALARM signal that's only unmasked for the thread that'll timeout. In the signal handler, you'll have to set a flag and use longjmp
to return to the thread code.
In the thread code, on the setjmp
position, you can only be called if the signal was triggered, thus you can throw the Timeout
exception.
Please see this answer for how to do that.
Also, on linux, it seems you can directly throw from the signal handler (so no longjmp/setjmp here).
BTW, if I were you, I would code the opposite. Think about it: You want to tell a thread "hey, you're taking too long, so let's throw away all the (long) work you've done so far so I can make progress".
Ideally, you should have your long thread be more cooperative, doing something like "I've done A of a ABCD task, let's release the mutex so other can progress on A. Then let's check if I can take it again to do B and so on."
You probably want to be more fine grained (have more mutex on smaller objects, but make sure you're locking in the same order) or use RW locks (so that other threads can use the objects if you're not modifying them), etc...
edited 57 mins ago
answered 1 hour ago
xryl669xryl669
1,4671327
1,4671327
add a comment |
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.
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%2f54598455%2fis-there-a-c-design-pattern-that-implements-a-mechanism-or-mutex-that-controls%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
5
AFAIK only the opposite is provided. I believe you need to write your own.
– NathanOliver
5 hours ago
4
The tricky part will be deciding how the thread that currently owns the lock will be notified or otherwise realize that it's lock now belongs to someone else.
– François Andrieux
5 hours ago
3
Isn't that a bit against the principle of "owning" a resource? Also, implementing a timeout when you have a lock might get awful in some cases performance-wise. Imagine a timeout of of 500ms but it would have took 505ms to complete all the work. What happens then?
– AlexG
5 hours ago
3
This sounds tricky. It may be that you will have to put regular checks in the worker thread whether or not to terminate. I mean what if you only partially modified the state of the resource leaving it in an unpredictable condition for the preempting thread to take over from?
– Galik
5 hours ago
2
The thread that owns the lock periodically checks to see how long it has held the lock, and if it exceeds the threshold it relinquishes the lock and does whatever cleanup required. The concept is similar to cooperative multitasking, in contrast to the much more prevalent preemptive multitasking. Note: there's a reason preemptive multitasking is more prevalent, even though it is less efficient than cooperative multitasking.
– Eljay
4 hours ago