#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <strings.h>
#include <unistd.h>
#include <signal.h>
#include <pthread.h>
pthread_mutex_t mutex;
pthread_mutexattr_t mattr;
pthread_t thread1;
pthread_t thread2;
pthread_t thread3;
void mutex_force_unlock(pthread_mutex_t *mutex, pthread_mutexattr_t *mattr)
{
int e;
e = pthread_mutex_destroy(mutex);
printf("mfu: %s\n", strerror(e));
e = pthread_mutex_init(mutex, mattr);
printf("mfu: %s\n", strerror(e));
}
void *thread(void *d)
{
int e;
e = pthread_mutex_trylock(&mutex);
if (e != 0)
{
printf("thr: %s\n", strerror(e));
mutex_force_unlock(&mutex, &mattr);
e = pthread_mutex_unlock(&mutex);
printf("thr: %s\n", strerror(e));
if (e != 0) pthread_exit(NULL);
e = pthread_mutex_lock(&mutex);
printf("thr: %s\n", strerror(e));
}
pthread_exit(NULL);
}
void * thread_deadtest(void *d)
{
int e;
e = pthread_mutex_lock(&mutex);
printf("thr2: %s\n", strerror(e));
e = pthread_mutex_lock(&mutex);
printf("thr2: %s\n", strerror(e));
pthread_exit(NULL);
}
int main(void)
{
/* Setup */
pthread_mutexattr_init(&mattr);
pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_ERRORCHECK);
//pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_NORMAL);
pthread_mutex_init(&mutex, &mattr);
/* Test */
pthread_create(&thread1, NULL, &thread, NULL);
pthread_join(thread1, NULL);
if (pthread_kill(thread1, 0) != 0) printf("Thread 1 has died.\n");
pthread_create(&thread2, NULL, &thread, NULL);
pthread_join(thread2, NULL);
pthread_create(&thread3, NULL, &thread_deadtest, NULL);
pthread_join(thread3, NULL);
return(0);
}
现在当这个程序运行时,我会得到以下输出:
Thread 1 has died.
thr: Device busy
mfu: Device busy
mfu: No error: 0
thr: Operation not permitted
thr2: No error: 0
thr2: Resource deadlock avoided
现在我知道这个问题已经被问了很多次,但是有没有办法强制解锁互斥锁?似乎实现只允许锁定它的线程解锁互斥锁,因为它似乎会主动检查,即使使用普通互斥锁类型也是如此。
我为什么要这样做?这与编写一个防弹网络服务器有关,该服务器具有从大多数错误中恢复的能力,包括线程意外终止的错误。目前,我看不到从与锁定它的线程不同的线程中解锁互斥锁的方法。所以我认为我有几个选择:
1. 放弃互斥锁并创建一个新的。这是不希望的选择,因为它会创建一个内存泄漏。 2. 关闭所有网络端口并重新启动服务器。 3. 进入内核内部并在那里释放互斥锁,绕过错误检查。
我之前已经问过这个问题before,但是决策者们非常想要这个功能,他们不会接受拒绝的回答(我已经试过了),所以我有点束手无策。我没有设计成这样,我真的很想枪毙那个设计者,但这也不是一个选项。
在有人说什么之前,我使用pthread_kill是符合POSIX标准的...我检查过了。
我忘了提到,我们正在使用FreeBSD 9.3。
pthread_mutex_t
吗?编写一个自己的锁,可以从其他线程释放它,基于它并不难。 - deviantfan