检查 pthread 互斥体是否被锁定或解锁(线程锁定自身之后)

2024-02-20

我需要查看 if 语句中互斥体是否被锁定或解锁,所以我像这样检查......

if(mutex[id] != 2){
    /* do stuff */
}

但是当我检查 gcc 时,出现以下错误:

error: invalid operands to binary != (have 'ptherad_mutex_t' and 'int')

那么如何检查互斥体是否被锁定呢?

EDIT:

我的问题的一个关键组成部分是我的线程(根据设计)在将控制权传递给另一个线程后立即锁定自己。因此,当线程 A 将控制权传递给线程 B 时,线程 A 被锁定,线程 B 执行一些操作,然后当线程 B 完成操作时,它将解锁线程 A。

这样做的问题是,如果线程 B 尝试解锁线程 A 并且线程 A 尚未完成锁定本身,则对解锁的调用将丢失,并且线程 A 保持锁定状态,从而导致死锁。

UPDATE:

我根据咖啡馆的建议重新编写了程序,但仍然遇到问题。我已尽我所能将我的程序模制到结构咖啡馆中,但我什至无法说出现在导致死锁的原因......我创建了一个新问题here https://stackoverflow.com/questions/4381782/pthread-program-deadlocks-using-condition-variables寻求有关我的代码的帮助。

以下是 caf 建议的可运行版本。我对线程 a 的函数进行了一个小的重新排序,否则线程 a 和线程 b 在创建时都会被锁定,等待永远不会改变的条件。

#include <pthread.h>

int run_a = 0;
pthread_mutex_t lock_a = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_a = PTHREAD_COND_INITIALIZER;

int run_b = 0;
pthread_mutex_t lock_b = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond_b = PTHREAD_COND_INITIALIZER;

void *a(void *);
void *b(void *);

int main(){
    int status;
    pthread_t thread_a;
    pthread_t thread_b;

    pthread_create(&thread_a, NULL, a, (void *)0);
    pthread_create(&thread_b, NULL, b, (void *)0);

    pthread_join(thread_a, (void **)&status);
    pthread_join(thread_b, (void **)&status);

}

/* thread A */
void *a(void *i){
    while (1) {
        printf("thread A is running\n");
        sleep(1);

        /* unlock thread B */
        pthread_mutex_lock(&lock_b);
            run_b = 1;
            pthread_cond_signal(&cond_b);
        pthread_mutex_unlock(&lock_b);

        /* wait for thread A to be runnable */
        pthread_mutex_lock(&lock_a);
            while (!run_a)
                pthread_cond_wait(&cond_a, &lock_a);
            run_a = 0;
        pthread_mutex_unlock(&lock_a);      
    }
}

/* thread B */
void *b(void *i){
    while (1) {
        /* wait for thread B to be runnable */
        pthread_mutex_lock(&lock_b);
            while (!run_b)
                pthread_cond_wait(&cond_b, &lock_b);
            run_b = 0;
        pthread_mutex_unlock(&lock_b);

        printf("thread B is running\n");
        sleep(1);

        /* unlock thread A */
        pthread_mutex_lock(&lock_a);
            run_a = 1;
            pthread_cond_signal(&cond_a);
        pthread_mutex_unlock(&lock_a);
    }
}

您可以使用pthread_mutex_trylock。如果成功,则互斥锁未被认领,并且您现在拥有它(因此您应该释放它并返回“未持有”,在您的情况下)。不然就有人拿着了。

我必须强调,“检查互斥体是否无人认领”是一个非常糟糕的主意。这种思维存在固有的竞争条件。如果这样的函数有时告诉你t锁未被持有,这绝对没有说明其他线程是否在t+1.

如果用代码示例可以更好地说明这一点,请考虑:

bool held = is_lock_held();

if (!held)
{
  // What exactly can you conclude here?  Pretty much nothing.
  // It was unheld at some point in the past but it might be held
  // by the time you got to this point, or by the time you do your
  // next instruction...
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

检查 pthread 互斥体是否被锁定或解锁(线程锁定自身之后) 的相关文章

  • C++ 维护子类对象的混合集合

    如果我在这里错过了一个相当基本的概念 我很抱歉 但我正在尝试弄清楚如何维护多个类类型的集合 所有类类型都派生自同一个父类 并且在检索它们时仍然可以访问它们的特定于子类的方法从集合中 作为上下文 我有一个基类 BaseClass 和许多类 例
  • 为什么在连接两个字符串时 Python 比 C 更快?

    目前我想比较 Python 和 C 用来处理字符串的速度 我认为 C 应该比 Python 提供更好的性能 然而 我得到了完全相反的结果 这是 C 程序 include
  • 计算 XML 中特定 XML 节点的数量

    请参阅此 XML
  • 使用 C# 登录《我的世界》

    我正在尝试为自己和一些朋友创建一个简单的自定义 Minecraft 启动器 我不需要启动 Minecraft 的代码 只需要登录的实际代码行 例如 据我所知 您过去可以使用 string netResponse httpGET https
  • 如何在C(Linux)中的while循环中准确地睡眠?

    在 C 代码 Linux 操作系统 中 我需要在 while 循环内准确地休眠 比如说 10000 微秒 1000 次 我尝试过usleep nanosleep select pselect和其他一些方法 但没有成功 一旦大约 50 次 它
  • 查找进程的完整路径

    我已经编写了 C 控制台应用程序 当我启动应用程序时 不使用cmd 我可以看到它列在任务管理器的进程列表中 现在我需要编写另一个应用程序 在其中我需要查找以前的应用程序是否正在运行 我知道应用程序名称和路径 所以我已将管理对象搜索器查询写入
  • 如何判断计算机是否已重新启动?

    我曾经使用过一个命令行 SMTP 邮件程序 作为试用版的限制 它允许您在每个 Windows 会话中最多接收 10 封电子邮件 如果您重新启动计算机 您可能还会收到 10 个以上 我认为这种共享软件破坏非常巧妙 我想在我的应用程序中复制它
  • 如何填充 ToolStripComboBox?

    我发现它很难将数据绑定到ToolStripComboBox 好像没有这个ValueMember and DisplayMember特性 怎么绑定呢 访问toolstripcombobox中包装的组合框并访问其ValueMember Disp
  • 如何使用 Castle Windsor 将对象注入到 WCF IErrorHandler 实现中?

    我正在使用 WCF 开发一组服务 该应用程序正在使用 Castle Windsor 进行依赖注入 我添加了一个IErrorHandler通过属性添加到服务的实现 到目前为止一切正常 这IErrorHandler对象 一个名为FaultHan
  • 函数参数的默认参数是否被视为该参数的初始值设定项?

    假设我有这样的函数声明 static const int R 0 static const int I 0 void f const int r R void g int i I 根据 dcl fct default 1 如果在参数声明中指
  • 从同一个类中的另一个构造函数调用构造函数

    我有一个带有两个构造函数的类 C 这是代码片段 public class FooBar public FooBar string s constructor 1 some functionality public FooBar int i
  • 从客户端访问 DomainService 中的自定义对象

    我正在使用域服务从 Silverlight 客户端的数据库中获取数据 在DomainService1 cs中 我添加了以下内容 EnableClientAccess public class Product public int produ
  • unordered_map 中字符串的 C++ 哈希函数

    看起来 C 标准库中没有字符串的哈希函数 这是真的 在任何 c 编译器上使用字符串作为 unordered map 中的键的工作示例是什么 C STL提供模板专业化 http en cppreference com w cpp string
  • File.AppendText 尝试写入错误的位置

    我有一个 C 控制台应用程序 它作为 Windows 任务计划程序中的计划任务运行 此控制台应用程序写入日志文件 该日志文件在调试模式下运行时会创建并写入应用程序文件夹本身内的文件 但是 当它在任务计划程序中运行时 它会抛出一个错误 指出访
  • 类型约束

    我有以下类层次结构 class Header IEnumerable
  • IQueryable 单元或集成测试

    我有一个 Web api 并且公开了一个端点 如下所示 api 假期 name name 这是 Web api 的控制器 get 方法 public IQueryable
  • 如何在 C 中安全地声明 16 位字符串文字?

    我知道已经有一个标准方法 前缀为L wchar t test literal L Test 问题是wchar t不保证是16位 但是对于我的项目 我需要16位wchar t 我还想避免通过的要求 fshort wchar 那么 C 不是 C
  • 保护 APK 中的字符串

    我正在使用 Xamarin 的 Mono for Android 开发一个 Android 应用程序 我目前正在努力使用 Google Play API 添加应用内购买功能 为此 我需要从我的应用程序内向 Google 发送公共许可证密钥
  • WebBrowser.Print() 等待完成。 。网

    我在 VB NET 中使用 WebBrowser 控件并调用 Print 方法 我正在使用 PDF 打印机进行打印 当调用 Print 时 它不会立即启动 它会等到完成整个子或块的运行代码 我需要确保我正在打印的文件也完整并继续处理该文件
  • 使用 C 在 OS X 中获取其他进程的 argv

    我想获得其他进程的argv 例如ps 我使用的是在 Intel 或 PowerPC 上运行的 Mac OS X 10 4 11 首先 我阅读了 ps 和 man kvm 的代码 然后编写了一些 C 代码 include

随机推荐