在进程之间共享条件变量和互斥锁:互斥锁之前是否必须锁定?

2023-11-30

我需要一些帮助来理解如何使用 C 中的条件变量来解决练习。这是一个小例子:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>

#define OKTOWRITE "/oktowrite"
#define MESSAGE "/message"
#define MUTEX "/lock"

int main(int argc, char** argv)
{
  pthread_cond_t* condition;
  pthread_mutex_t *mutex;
  char* message;
  int des_cond, des_msg, des_mutex;
  int mode = S_IRWXU | S_IRWXG;

  des_mutex = shm_open(MUTEX, O_CREAT | O_RDWR | O_TRUNC, mode);

  if (des_mutex < 0)
  {
    perror("failure on shm_open on des_mutex");
    exit(1);
  }

  if (ftruncate(des_mutex, sizeof(pthread_mutex_t)) == -1)
  {
    perror("Error on ftruncate to sizeof pthread_cond_t\n");
    exit(-1);
  }

  mutex = (pthread_mutex_t*) mmap(NULL, sizeof(pthread_mutex_t),
      PROT_READ | PROT_WRITE, MAP_SHARED, des_mutex, 0);

  if (mutex == MAP_FAILED )
  {
    perror("Error on mmap on mutex\n");
    exit(1);
  }

  pthread_mutex_init(mutex, NULL );

  des_cond = shm_open(OKTOWRITE, O_CREAT | O_RDWR | O_TRUNC, mode);

  if (des_cond < 0)
  {
    perror("failure on shm_open on des_cond");
    exit(1);
  }

  if (ftruncate(des_cond, sizeof(pthread_cond_t)) == -1)
  {
    perror("Error on ftruncate to sizeof pthread_cond_t\n");
    exit(-1);
  }

  condition = (pthread_cond_t*) mmap(NULL, sizeof(pthread_cond_t),
      PROT_READ | PROT_WRITE, MAP_SHARED, des_cond, 0);

  if (condition == MAP_FAILED )
  {
    perror("Error on mmap on condition\n");
    exit(1);
  }

  pthread_cond_init(condition, NULL );

  if (!fork())
  {
    sleep(3);
    pthread_mutex_lock(mutex);
    pthread_cond_signal(condition);
    pthread_mutex_unlock(mutex);
    printf("son signaled\n");
    exit(0);
  }
  else
  {
    printf("wait on condition\n");

    pthread_mutex_lock(mutex);
    pthread_cond_wait(condition, mutex);
    pthread_mutex_unlock(mutex);

    printf("Signaled by son process, wake up\n");

    pthread_mutex_destroy(mutex);
    pthread_cond_destroy(condition);

    shm_unlink(OKTOWRITE);
    shm_unlink(MESSAGE);
    shm_unlink(MUTEX);

    return 0;
  }
}

问题是,即使在儿子发出信号之后,该进程的父亲仍然被锁定。一切都在共享内存中(使用shm_open and mmap)因此两个过程的条件应该相同。 在调用 wait 或 signal 之前锁定互斥锁可能会犯错误吗?

编辑: 感谢所有帮助过我的人。这是正确的代码,其中标记了关键部分:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>

#define OKTOWRITE "/condwrite"
#define MESSAGE "/msg"
#define MUTEX "/mutex_lock"

int main(int argc, char** argv) {

pthread_cond_t* condition;
pthread_mutex_t* mutex;
char* message;
int des_cond, des_msg, des_mutex;
int mode = S_IRWXU | S_IRWXG;

des_mutex = shm_open(MUTEX, O_CREAT | O_RDWR | O_TRUNC, mode);

if (des_mutex < 0) {
    perror("failure on shm_open on des_mutex");
    exit(1);
}

if (ftruncate(des_mutex, sizeof(pthread_mutex_t)) == -1) {
    perror("Error on ftruncate to sizeof pthread_cond_t\n");
    exit(-1);
}

mutex = (pthread_mutex_t*) mmap(NULL, sizeof(pthread_mutex_t),
        PROT_READ | PROT_WRITE, MAP_SHARED, des_mutex, 0);

if (mutex == MAP_FAILED ) {
    perror("Error on mmap on mutex\n");
    exit(1);
}

des_cond = shm_open(OKTOWRITE, O_CREAT | O_RDWR | O_TRUNC, mode);

if (des_cond < 0) {
    perror("failure on shm_open on des_cond");
    exit(1);
}

if (ftruncate(des_cond, sizeof(pthread_cond_t)) == -1) {
    perror("Error on ftruncate to sizeof pthread_cond_t\n");
    exit(-1);
}

condition = (pthread_cond_t*) mmap(NULL, sizeof(pthread_cond_t),
        PROT_READ | PROT_WRITE, MAP_SHARED, des_cond, 0);

if (condition == MAP_FAILED ) {
    perror("Error on mmap on condition\n");
    exit(1);
}


         /* HERE WE GO */
/**************************************/

    /* set mutex shared between processes */
pthread_mutexattr_t mutexAttr;
pthread_mutexattr_setpshared(&mutexAttr, PTHREAD_PROCESS_SHARED);
pthread_mutex_init(mutex, &mutexAttr);

/* set condition shared between processes */
pthread_condattr_t condAttr;
pthread_condattr_setpshared(&condAttr, PTHREAD_PROCESS_SHARED);
pthread_cond_init(condition, &condAttr);

    /*************************************/

if (!fork()) {

    sleep(10);

    pthread_mutex_lock(mutex);
    pthread_cond_signal(condition);
    printf("son signaled\n");
    pthread_mutex_unlock(mutex);
    exit(0);
}

else {

    printf("father waits on condition\n");

     pthread_mutex_lock(mutex);
     pthread_cond_wait(condition, mutex);
     pthread_mutex_unlock(mutex);

     printf("Signaled by son process, wake up!!!!!!!!\n");

    pthread_condattr_destroy(&condAttr);
    pthread_mutexattr_destroy(&mutexAttr);
    pthread_mutex_destroy(mutex);
    pthread_cond_destroy(condition);

    shm_unlink(OKTOWRITE);
    shm_unlink(MESSAGE);
    shm_unlink(MUTEX);

}

return 0;

}

为了在进程之间共享互斥锁,需要通过正确初始化的属性进行相应的初始化:http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_mutexattr_setpshared.html

#include <pthread.h>

...

pthread_mutex_t * pmutex = NULL;
pthread_mutexattr_t attrmutex;

/* Initialise attribute to mutex. */
pthread_mutexattr_init(&attrmutex);
pthread_mutexattr_setpshared(&attrmutex, PTHREAD_PROCESS_SHARED);

/* Allocate memory to pmutex here. */

/* Initialise mutex. */
pthread_mutex_init(pmutex, &attrmutex);

/* Use the mutex. */

/* Clean up. */
pthread_mutex_destroy(pmutex);
pthread_mutexattr_destroy(&attrmutex); 

(error checking left out for the sake of this example's readability)

这同样适用于应在进程之间共享的条件变量:http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_condattr_setpshared.html

#include <pthread.h>

...

pthread_cond_t * pcond = NULL;
pthread_condattr_t attrcond;

/* Initialise attribute to condition. */
pthread_condattr_init(&attrcond);
pthread_condattr_setpshared(&attrcond, PTHREAD_PROCESS_SHARED);

/* Allocate memory to pcond here. */

/* Initialise condition. */
pthread_cond_init(pcond, &attrcond);

/* Use the condition. */

/* Clean up. */
pthread_cond_destroy(pcond);
pthread_condattr_destroy(&attrcond); 

(error checking left out for the sake of this example's readability)


另请参阅这个答案:https://stackoverflow.com/a/2390670/694576

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在进程之间共享条件变量和互斥锁:互斥锁之前是否必须锁定? 的相关文章

  • GCC C++ (ARM) 和指向结构体字段的 const 指针

    假设有一个简单的测试代码 typedef struct int first int second int third type t define ADDRESS 0x12345678 define REGISTER type t ADDRE
  • MEX 文件中的断言导致 Matlab 崩溃

    我正在使用mxAssert 宏定义为matrix h在我的 C 代码中 mex 可以完美编译 当我调用的 mex 代码中违反断言时 该断言不会导致我的程序崩溃 而是导致 Matlab 本身崩溃 我错过了什么吗 这是有意的行为吗 当我查看 M
  • Qt - 无法让 lambda 工作[重复]

    这个问题在这里已经有答案了 我有以下功能 我想在其中修剪我的std set
  • Blazor 与 Razor

    随着 Blazor 的发明 我想知道这两种语言之间是否存在显着的效率 无论是在代码创建方面还是在代码的实际编译 执行方面 https github com SteveSanderson Blazor https github com Ste
  • 通信对象 System.ServiceModel.Channels.ServiceChannel 不能用于通信

    通信对象System ServiceModel Channels ServiceChannel 无法用于通信 因为它处于故障状态 这个错误到底是什么意思 我该如何解决它 您收到此错误是因为您让服务器端发生 NET 异常 并且您没有捕获并处理
  • 使用实体框架从集合中删除项目

    我正在使用DDD 我有一个 Product 类 它是一个聚合根 public class Product IAggregateRoot public virtual ICollection
  • 在 C++11 中省略返回类型

    我最近发现自己在 C 11 模式下的 gcc 4 5 中使用了以下宏 define RETURN x gt decltype x return x 并编写这样的函数 template
  • std::map 和二叉搜索树

    我读过 std map 是使用二叉搜索树数据结构实现的 BST 是一种顺序数据结构 类似于数组中的元素 它将元素存储在 BST 节点中并按其顺序维护元素 例如如果元素小于节点 则将其存储在节点的左侧 如果元素大于节点 则将其存储在节点的右侧
  • 为什么 BOOST_FOREACH 不完全等同于手工编码的?

    From 增强文档 http www boost org doc libs 1 48 0 doc html foreach html foreach introduction what is literal boost foreach li
  • 单元测试失败,异常代码为 c0000005

    我正在尝试使用本机单元测试项目在 Visual Studios 2012 中创建单元测试 这是我的测试 TEST METHOD CalculationsRoundTests int result Calculations Round 1 0
  • 事件日志写入错误

    很简单 我想向事件日志写入一些内容 protected override void OnStop TODO Add code here to perform any tear down necessary to stop your serv
  • 组合框项目为空但数据源已满

    将列表绑定到组合框后 其 dataSource Count 为 5 但组合框项目计数为 0 怎么会这样 我习惯了 Web 编程 而且这是在 Windows 窗体中进行的 所以不行combo DataBind 方法存在 这里的问题是 我试图以
  • C# 编译器如何决定发出可重定向的程序集引用?

    NET Compact Framework 引入了可重定向程序集引用 现在用于支持可移植类库 基本上 编译器会发出以下 MSIL assembly extern retargetable mscorlib publickeytoken 7C
  • C# 搜索目录中包含字符串的所有文件,然后返回该字符串

    使用用户在文本框中输入的内容 我想搜索目录中的哪个文件包含该文本 然后我想解析出信息 但我似乎找不到该字符串或至少返回信息 任何帮助将不胜感激 我当前的代码 private void btnSearchSerial Click object
  • Silverlight Datagrid:在对列进行排序时突出显示整个列

    我的 Silverlight 应用程序中有一个 DataGrid 我想在对该列进行排序时突出显示整个列 它在概念上与上一个问题类似 Silverlight DataGrid 突出显示整列 https stackoverflow com qu
  • 过度使用委托对性能来说是一个坏主意吗? [复制]

    这个问题在这里已经有答案了 考虑以下代码 if IsDebuggingEnabled instance Log GetDetailedDebugInfo GetDetailedDebugInfo 可能是一个昂贵的方法 因此我们只想在调试模式
  • 以编程方式使用自定义元素创建网格

    我正在尝试以编程方式创建一个网格 并将自定义控件作为子项附加到网格中 作为 2x2 矩阵中的第 0 行第 0 列 为了让事情变得更棘手 我使用了 MVVM 设计模式 下面是一些代码可以帮助大家理解这个想法 应用程序 xaml cs base
  • Azure函数版本2.0-应用程序blobTrigger不工作

    我有一个工作功能应用程序 它有一个 blob 输入和一个事件中心输出 在测试版中工作 随着最新的更改 我的功能不再起作用 我尝试根据发行说明更新 host json 文件 但它没有引用 blob 触发器 version 2 0 extens
  • 从类模板参数为 asm 生成唯一的字符串文字

    我有一个非常特殊的情况 我需要为类模板中声明的变量生成唯一的汇编程序名称 我需要该名称对于类模板的每个实例都是唯一的 并且我需要将其传递给asm关键字 see here https gcc gnu org onlinedocs gcc 12
  • 如何确定母版页中正在显示哪个子页?

    我正在母版页上编写代码 我需要知道正在显示哪个子 内容 页面 我怎样才能以编程方式做到这一点 我用这个 string pageName this ContentPlaceHolder1 Page GetType FullName 它以 AS

随机推荐

  • QSqlQuery 准备好的语句 - 正确使用

    我正在尝试确定将准备好的语句与 QSqlQuery 一起使用的正确方法 这些文档对于这个主题不是很具体 void select const QSqlDatabase database QSqlQuery query database que
  • 如何使用 Golem Shiny 应用程序将 4 个盒子排成一排?

    我正在尝试将每行 4 个盒子放入我闪亮的应用程序中 BioTuring 和 Scope 我希望与 FLAT 和 GTEx 对齐在同一行 现在看起来是这样的 需要注意的是 这个应用程序是用 golem 结构完成的 因此 请在帮助时牢记并遵循我
  • 从 .mexglx 到 .mex

    我得到了一个使用外部 C 函数的 Matlab 程序 我只有这个外部函数的编译版本 扩展名是 mexglx 从我已经红色的来看 这个扩展似乎是用linux编译的mex文件版本 我在 Windows XP 下运行 matlab 我的问题是我的
  • 如何通过 NPM 脚本使用 Windows 控制台“设置”变量?

    这在 Windows 控制台中按预期工作 set A qwerty echo A 输出 qwerty 但是当我尝试在 NPM 脚本中运行相同的命令时 包 json scripts qwerty set A qwerty echo A gt
  • 使用 JavaScript 自动填写表单

    这是我的代码 function setActualDate var d1 new Date var y d1 getFullYear var d d1 getDate var m1 d1 getMonth 1 var m2 d1 getMo
  • HttpURLConnection POST,conn.getOutputStream() 抛出异常

    我想使用 HttpURLConnection 进行 POST 我正在以两种方式尝试这一点 但在执行时我总是会遇到异常 conn getOutputStream 我在这两种情况下得到的例外是 java net SocketException
  • Java Spring-data Mongo中的Mongodb请求

    我在文档中有一个数组 id id 1 name name 1 additionalData additionalDataId id 1 1 additionalDataName name 1 1 longText A long story
  • 创建一个pandas表

    在使用 pandas 时 如何显示与此类似的表格 我想我必须使用类似于的数据框df pandas DataFrame results 并显示它display display df 但从那里我不知道该怎么办 您可以将字典传递为data当你使用
  • 如何传递带有存储在单个变量中的引号的命令行参数?

    我想从 shell 脚本调用外部应用程序 但此 shell 脚本在单个变量中获取参数 来自其他脚本 一切都很好 直到我不必对单个参数使用双引号 而是用空格分隔单词 这是我的问题的简化示例 sh param 只是打印所有传递的参数 bin s
  • 在消息框中显示非英语文本

    我在 MS Access 中的应用程序中编写了以下代码 以波斯语 非英语 显示消息框 但是当我输入波斯语 Persion 时 它会键入一些特殊 未知 不同的字符 而且当我运行应用程序时 消息框显示特殊 不同的字符 而不是我想要显示的 msg
  • 在 boost::asio 的上下文中,术语“strand”背后的隐喻是什么?

    As a French native and a boost asio user I have added the strand word to my vocabulary is a toron in French here an imag
  • JAVA链表如何用for循环进行循环?

    您好 我正在尝试创建一个循环遍历链表的 for 循环 对于每条数据 它都会单独列出 我想在这里学习链表 所以没有数组建议 有人知道怎么做吗 示例输出 187 航班 501航班 到目前为止我的代码如下 public static Linked
  • 模拟 subprocess.Popen 依赖于导入样式

    当尝试模拟 Popen 时 只有当子进程的导入在单元测试代码和主模块代码中都匹配时 我才能使其成功 给出以下模块 listdir py from subprocess import Popen PIPE def listdir dir cm
  • ActiveMQ 5.11 与 WebSphere 应用程序服务器 8.5

    有谁知道我需要将 ActiveMQ 5 11 中的哪些 jar 与 IBM Websphere Application Server 8 5 一起使用才能创建新的 ActiveMQ JMS 提供程序 我发现与旧版 ActiveMQ 相关的讨
  • iOS 和 OSX 上的 Captive Network Assistant 上的 Ajax

    ajax 可以工作吗强制网络助手在 iOS 和 OSX 上 我在用jquery执行以下操作 但不起作用 这响应文本变量既不是 true 也不是 false 在适当的 Safari 浏览器以及 Android 和 Windows 设备上运行良
  • 从 sympy 求解二阶微分方程组

    我正在使用二阶拉格朗日方程解决多自由度动力学问题 我使用 sympy 来获取运动方程 现在计算导数后这些方程变得相当长 尽管 sympy 简化似乎无法进一步简化它 我的问题实际上是如何从这里解决这个由三个二阶颂歌组成的系统 我不知道如何转换
  • 如何实施单点登录

    我想实现 SSO 单点登录 我发现了很多关于 CAS OpenID 和许多不同事物的链接和文章 我真的迷失了那么我应该使用 CAS 吗 我安装了 CAS Server 并将其部署到 Tomcat 中 你下一步怎么做 或者这是错误的 您能解释
  • 使用 Facebook SDK 4.1.2 创建登录按钮时出现问题

    我正在尝试创建一个应用程序 该应用程序将允许用户通过他们的 Facebook 帐户登录 我想通过 eclipse 使用新的 Facebook SDK 4 1 2 为了在 eclipse 中使用新的 SDK 我遵循本教程 我现在可以在不使用
  • Wix RemoveFile 和 RemoveFolder 用于删除剩余内容

    我有以下 wix 文件 该文件应该在安装过程中调用自定义操作 自定义操作将创建程序所需的一些文件 由于 Wix 只会删除安装程序安装的文件 因此自定义操作创建的文件将被保留 所以我求助于删除文件由维克斯提供 我有以下 Wix 文件
  • 在进程之间共享条件变量和互斥锁:互斥锁之前是否必须锁定?

    我需要一些帮助来理解如何使用 C 中的条件变量来解决练习 这是一个小例子 include