One mutex for each possible
n
value, provided that the range of
n
isn't huge?
1 2 3 4 5 6 7
|
mutex_t mutex[N];
void process(int n) {
mutex_lock(&mutex[n]);
// Perform process
mutex_unlock(&mutex[n]);
}
| |
If this is
not feasible, e.g. because the range of
n
is too big, maybe use a condition variable?
https://pages.cs.wisc.edu/~remzi/OSTEP/threads-cv.pdf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
cond_var_t cond_var;
mutex_t mutex;
std::set<int> set;
void process(int n) {
mutex_lock(&mutex);
while (set.contains(n)) {
cond_var_wait(&cond_var, &mutex); //wait for the flag to become clear
}
set.insert(n); // set the flag for ourselves
mutex_unlock(&mutex);
// Perform process
// ...
mutex_lock(&mutex);
set.remove(n); // finally, clear the flag
mutex_unlock(&mutex);
cond_var_broadcast(&cond_var); // ...and wake any waiters
}
| |
Note that, in the non-congested case, we
temporarily lock the mutex, in order to
atomically update the "shared" set.
...but it won't be locked for the whole time, so parallel processing (of different
n
values) remains possible.
Also note that
cond_var_wait()
unlocks the given mutex while sleeping, and it automatically re-locks that mutex on wake-up.