无条件等待互斥体
Wait on a Mutex without Conditions
我有一项任务需要在何处进行一些线程管理。问题是我只被允许使用一个互斥量,仅此而已,没有更多的条件或其他任何东西。
我有一个结构,其中包含一些数据,其中 2 个线程更改和一个互斥体。该结构排列在一个数组中,并通过索引访问。
编辑:我认为这是一个更好的解释。问题是我遇到了死锁,因为 thread2 仍然持有锁而 thread1 想要获取它,或者有时相反。
typedef struct {
int number;
pthread_mutex_t mutex;
} data;
data myStruct[100];
void* thread1()
{
pthread_mutex_lock(&myStruct[index].mutex)
// get 1 index value
// access the struct via index
// change a value
pthread_mutex_unlock(&myStruct[index].mutex)
}
void* thread2()
{
pthread_mutex_lock(&myStruct[index1].mutex)
pthread_mutex_lock(&myStruct[index2].mutex)
// get 2 index values
// access struct with both indexes
// change values with both indexes
pthread_mutex_unlock(&myStruct[index2].mutex)
pthread_mutex_unlock(&myStruct[index1].mutex)
}
指标值是通过一些随机计算得到的。 Mutex初始化销毁,线程创建不在我手上
我有 2 个线程。两个线程都可以访问其中的结构和互斥量。并且必须使用这个互斥锁来锁定和解锁数据。线程 1 仅更改一个数据结构中的数据,线程 2 更改两个数据结构中的数据。
问题是我必须在两个线程中等待互斥体,目前我通过
解决了它
while(pthread_mutex_lock(&struct[i].lock) != 0)
它有时会起作用,但我不知道我应该如何只用这个互斥锁来锁定。我不允许创建更多的互斥量、信号量或条件。
你有什么想法可以尝试吗?
如果互斥量被另一个线程锁定,pthread_mutex_lock(&struct[i].lock)
调用将自身阻塞。无需使用轮询 while 循环。参见 manpage:
The mutex object referenced by mutex shall be locked by calling
pthread_mutex_lock(). If the mutex is already locked, the calling
thread shall block until the mutex becomes available.
还记得通过 pthread_mutex_unlock((&struct[i].lock)
解锁互斥锁。
编辑#1:
您正在使用多个互斥体,因为您声明了一个数组:data myStruct[100]
。所以你必须解锁正确的互斥锁或者只对整个数组使用一个互斥锁。
编辑#2:
您的代码看起来是正确的,因此您的线程似乎从未达到 unlock statement
,您应该搜索它。
如果你只想使用一个互斥锁,你可以这样
typedef struct {
int* number;
pthread_mutex_t mutex;
} data;
其中 int* number
是指向数据数组的指针。当然这个指针必须指向有效数据。
您的代码似乎存在死锁的可能性。如果 thread1
函数获取第一个互斥锁,而 thread2
函数获取第二个互斥锁,则所有资源都可能被捆绑和锁定。我认为你应该尝试类似的方法,
...
pthread_mutex_lock(&mutex_1);
while ( pthread_mutex_trylock(&mutex_2) ) /* Test if already locked */
{
pthread_mutex_unlock(&mutex_1); /* Free resource to avoid deadlock */
...
/* stall here */
...
pthread_mutex_lock(&mutex_1);
}
// count++; or yadda yadda yadda
pthread_mutex_unlock(&mutex_1);
pthread_mutex_unlock(&mutex_2);
...
我假设这个练习的全部目的是教你 "global lock order" 的概念。
这个想法是,你给所有的锁一个顺序,当获得 2 个或更多锁时,确保你以那个顺序获得它们,而当释放它们时,确保你以相反的顺序释放它们。这确保您永远不会陷入 "thread1 has lock1 and wants lock2, but thread2 has lock2 and wants thread1" 风格的僵局。
实际上,这可能类似于:
void* thread2()
{
if(index1 < index2) {
temp = index1; index1 = index2; index2 = temp;
}
pthread_mutex_lock(&myStruct[index1].mutex)
pthread_mutex_lock(&myStruct[index2].mutex)
// get 2 index values
// access struct with both indexes
// change values with both indexes
pthread_mutex_unlock(&myStruct[index2].mutex)
pthread_mutex_unlock(&myStruct[index1].mutex)
}
或者(如果 index1
和 index2
不可互换):
void* thread2()
{
if(index1 < index2) {
pthread_mutex_lock(&myStruct[index1].mutex)
pthread_mutex_lock(&myStruct[index2].mutex)
// get 2 index values
// access struct with both indexes
// change values with both indexes
pthread_mutex_unlock(&myStruct[index2].mutex)
pthread_mutex_unlock(&myStruct[index1].mutex)
} else {
pthread_mutex_lock(&myStruct[index2].mutex)
pthread_mutex_lock(&myStruct[index1].mutex)
// get 2 index values
// access struct with both indexes
// change values with both indexes
pthread_mutex_unlock(&myStruct[index1].mutex)
pthread_mutex_unlock(&myStruct[index2].mutex)
}
}
我有一项任务需要在何处进行一些线程管理。问题是我只被允许使用一个互斥量,仅此而已,没有更多的条件或其他任何东西。
我有一个结构,其中包含一些数据,其中 2 个线程更改和一个互斥体。该结构排列在一个数组中,并通过索引访问。
编辑:我认为这是一个更好的解释。问题是我遇到了死锁,因为 thread2 仍然持有锁而 thread1 想要获取它,或者有时相反。
typedef struct {
int number;
pthread_mutex_t mutex;
} data;
data myStruct[100];
void* thread1()
{
pthread_mutex_lock(&myStruct[index].mutex)
// get 1 index value
// access the struct via index
// change a value
pthread_mutex_unlock(&myStruct[index].mutex)
}
void* thread2()
{
pthread_mutex_lock(&myStruct[index1].mutex)
pthread_mutex_lock(&myStruct[index2].mutex)
// get 2 index values
// access struct with both indexes
// change values with both indexes
pthread_mutex_unlock(&myStruct[index2].mutex)
pthread_mutex_unlock(&myStruct[index1].mutex)
}
指标值是通过一些随机计算得到的。 Mutex初始化销毁,线程创建不在我手上
我有 2 个线程。两个线程都可以访问其中的结构和互斥量。并且必须使用这个互斥锁来锁定和解锁数据。线程 1 仅更改一个数据结构中的数据,线程 2 更改两个数据结构中的数据。
问题是我必须在两个线程中等待互斥体,目前我通过
解决了它while(pthread_mutex_lock(&struct[i].lock) != 0)
它有时会起作用,但我不知道我应该如何只用这个互斥锁来锁定。我不允许创建更多的互斥量、信号量或条件。
你有什么想法可以尝试吗?
如果互斥量被另一个线程锁定,pthread_mutex_lock(&struct[i].lock)
调用将自身阻塞。无需使用轮询 while 循环。参见 manpage:
The mutex object referenced by mutex shall be locked by calling pthread_mutex_lock(). If the mutex is already locked, the calling thread shall block until the mutex becomes available.
还记得通过 pthread_mutex_unlock((&struct[i].lock)
解锁互斥锁。
编辑#1:
您正在使用多个互斥体,因为您声明了一个数组:data myStruct[100]
。所以你必须解锁正确的互斥锁或者只对整个数组使用一个互斥锁。
编辑#2:
您的代码看起来是正确的,因此您的线程似乎从未达到 unlock statement
,您应该搜索它。
如果你只想使用一个互斥锁,你可以这样
typedef struct {
int* number;
pthread_mutex_t mutex;
} data;
其中 int* number
是指向数据数组的指针。当然这个指针必须指向有效数据。
您的代码似乎存在死锁的可能性。如果 thread1
函数获取第一个互斥锁,而 thread2
函数获取第二个互斥锁,则所有资源都可能被捆绑和锁定。我认为你应该尝试类似的方法,
...
pthread_mutex_lock(&mutex_1);
while ( pthread_mutex_trylock(&mutex_2) ) /* Test if already locked */
{
pthread_mutex_unlock(&mutex_1); /* Free resource to avoid deadlock */
...
/* stall here */
...
pthread_mutex_lock(&mutex_1);
}
// count++; or yadda yadda yadda
pthread_mutex_unlock(&mutex_1);
pthread_mutex_unlock(&mutex_2);
...
我假设这个练习的全部目的是教你 "global lock order" 的概念。
这个想法是,你给所有的锁一个顺序,当获得 2 个或更多锁时,确保你以那个顺序获得它们,而当释放它们时,确保你以相反的顺序释放它们。这确保您永远不会陷入 "thread1 has lock1 and wants lock2, but thread2 has lock2 and wants thread1" 风格的僵局。
实际上,这可能类似于:
void* thread2()
{
if(index1 < index2) {
temp = index1; index1 = index2; index2 = temp;
}
pthread_mutex_lock(&myStruct[index1].mutex)
pthread_mutex_lock(&myStruct[index2].mutex)
// get 2 index values
// access struct with both indexes
// change values with both indexes
pthread_mutex_unlock(&myStruct[index2].mutex)
pthread_mutex_unlock(&myStruct[index1].mutex)
}
或者(如果 index1
和 index2
不可互换):
void* thread2()
{
if(index1 < index2) {
pthread_mutex_lock(&myStruct[index1].mutex)
pthread_mutex_lock(&myStruct[index2].mutex)
// get 2 index values
// access struct with both indexes
// change values with both indexes
pthread_mutex_unlock(&myStruct[index2].mutex)
pthread_mutex_unlock(&myStruct[index1].mutex)
} else {
pthread_mutex_lock(&myStruct[index2].mutex)
pthread_mutex_lock(&myStruct[index1].mutex)
// get 2 index values
// access struct with both indexes
// change values with both indexes
pthread_mutex_unlock(&myStruct[index1].mutex)
pthread_mutex_unlock(&myStruct[index2].mutex)
}
}