c - 强制解锁由不同线程锁定的互斥体

标签 c multithreading pthreads freebsd

考虑以下测试程序:

#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。

最佳答案

使用 robust mutex , 如果锁定线程死了,用 pthread_mutex_consistent() 修复互斥量.

If mutex is a robust mutex in an inconsistent state, the pthread_mutex_consistent() function can be used to mark the state protected by the mutex referenced by mutex as consistent again.

If an owner of a robust mutex terminates while holding the mutex, the mutex becomes inconsistent and the next thread that acquires the mutex lock shall be notified of the state by the return value [EOWNERDEAD]. In this case, the mutex does not become normally usable again until the state is marked consistent.

If the thread which acquired the mutex lock with the return value [EOWNERDEAD] terminates before calling either pthread_mutex_consistent() or pthread_mutex_unlock(), the next thread that acquires the mutex lock shall be notified about the state of the mutex by the return value [EOWNERDEAD].

关于c - 强制解锁由不同线程锁定的互斥体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29882647/

相关文章:

c - Kadane 算法中的查询

C 数组段错误仅在特定阈值之后

c - 我应该在哪里创建 pthread

c++ - 为什么 pthread_key_create 析构函数被调用了几次?

c - 递归二分查找c

Java HashMap.get(Object) 无限循环

pandas - 为什么 Pandas 创建多个线程,而其内部操作是单线程的?

java - 无法从其他类(线程)的 Vector 获取元素

c - 线程和同步

c - 循环询问用户是否想再玩一次(y/n)