Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 使用两种不同状态同步两个进程_C_Linux_Shared Memory - Fatal编程技术网

C 使用两种不同状态同步两个进程

C 使用两种不同状态同步两个进程,c,linux,shared-memory,C,Linux,Shared Memory,我正试图找到一种方法来同步两个共享数据的进程 基本上,我有两个使用共享内存链接的进程。我需要进程A在共享内存区域中设置一些数据,然后进程B读取这些数据并对其执行操作 我期待的事件顺序是: B块等待数据可用信号 A写数据 A表示数据可用 B读取数据 B块等待数据不可用信号 A信号数据不可用 一切都回到了开始 换句话说,B将阻塞直到它得到一个“1”信号,获取数据,然后再次阻塞直到该信号变为“0” 我已经尝试使用纯粹的共享内存来模拟OK,但是要么我使用消耗100%CPU时间的while循环来阻止,要么

我正试图找到一种方法来同步两个共享数据的进程

基本上,我有两个使用共享内存链接的进程。我需要进程A在共享内存区域中设置一些数据,然后进程B读取这些数据并对其执行操作

我期待的事件顺序是:

  • B块等待数据可用信号
  • A写数据
  • A表示数据可用
  • B读取数据
  • B块等待数据不可用信号
  • A信号数据不可用
  • 一切都回到了开始
  • 换句话说,B将阻塞直到它得到一个“1”信号,获取数据,然后再次阻塞直到该信号变为“0”

    我已经尝试使用纯粹的共享内存来模拟OK,但是要么我使用消耗100%CPU时间的while循环来阻止,要么我使用一个带有纳秒睡眠的while循环,有时会错过一些信号

    我尝试过使用信号量,但我只能找到一种方法等待零,而不是一,尝试使用两个信号量根本不起作用。我不认为信号灯是正确的选择

    将有许多进程都访问相同的共享内存区域,并且当该共享内存被修改时,需要通知所有进程

    它基本上是试图模拟硬件数据和控制总线,其中事件是边缘触发的,而不是级别触发的。我感兴趣的是状态之间的转换,而不是状态本身


    那么,有什么想法吗?

    如果涉及两个进程,您可以使用文件、共享内存甚至网络来传递标志或信号。但是如果进程更多,那么在修改内核时可能会有一些合适的解决方案。你的问题中有一个共同的记忆,对吧?!现在信号是怎么传递的

    Linux有自己的功能,您可以将它合并到正常的
    轮询
    /
    选择
    循环中。您可以通过UNIX套接字以通常的方式将
    eventfd
    文件描述符从一个进程传递到另一个进程,也可以使用
    fork(2)
    继承它

    编辑0:
    重读这个问题后,我认为您的选项之一是信号和进程组:在同一进程组()下启动“侦听”进程,然后用负
    pid
    参数将它们全部发送到或。同样,Linux提供轮询和避免慢信号蹦床。

    在Linux中,所有POSIX控制结构(互斥、条件、读写锁、信号量)都有一个选项,如果它们位于共享内存中,也可以在进程之间使用。对于您描述的过程,一个经典的互斥/条件对似乎非常适合这个工作。查看这些结构的
    …\u init
    函数的手册页


    Linux还有其他合适的实用程序,比如“futex”,可以更有效地处理这个问题。但这些可能不是开始使用的正确工具。

    1单读写器
    1个单一读写器 这可以使用信号量实现。 在posix信号量api中,您有一个sem_wait(),它将一直等到信号量计数的值为零,然后使用来自其他进程的sem_post将其递增,等待将完成

    在这种情况下,必须使用2个信号量进行同步

    过程1(读卡器)
    sem_wait(sem1)
    ....
    sem_post(sem2)

    过程2(编写器)
    sem_-wait(sem2)
    ....
    高级管理人员职位(高级管理人员职位1)


    通过这种方式,您可以在共享内存中实现同步。

    循环如何消耗100%的内存?PS:您可以看看如何使用pthreads数据结构,在本例中是条件变量。(是的,我知道您使用的是单独的进程,但是您可以在共享内存段中抛出condvar)哎呀。。这应该是100%的cpu时间。@H2CO3信号会很好,但我无法预测哪些进程将访问共享内存。它可能有许多进程。共享内存听起来像是问题的根源。为什么不使用一个更合适的IPC机制呢?我所能做的最好的事情就是拥有第二个共享内存字节,其中包含标志,充当“控制”行。进程通过在while()循环中重复轮询来等待该字节中的更改。不过,这太需要处理器了。即使使用nanosleep,增加延迟也意味着错过了一些更改。我仍然需要这个额外的字节来控制其他事情,但需要某种方式在它发生变化时通知。它可能每秒改变数千次,多个进程需要知道这一点。进程a将信号放入第二个共享内存,以便向进程B通知新数据。当B没有全部读取第二个共享内存及其标志时,可以处理A更改吗?!正如你所说的,进程A可以改变它,确切地说,现在,B处于纳米睡眠状态,对吗?是的,A可以随时改变数据,无论B是否读取数据。实际上,进程A就像一个CPU,只是在地址和数据总线上设置值。过程B就像一个RAM芯片,等待特定总线上的特定组合,然后再对它们做出反应。进程A无法等待B的确认,因为B可能不会响应当前数据。可能是C做出响应,或者是Q,或者根本没有响应。我无法预测什么会或不会负责处理共享内存中的数据。当我遇到这种模式时,我脑海中会闪过一个队列。我知道这里的问题是不同的,但如果进程A可以等待B的信号来读取标志,以确保A获得有关标志的传递,那么问题似乎已经解决,但如果进程数量增加,这将是一个糟糕的解决方案。你也可以说进程A不等待任何东西。另一种情况是,进程A将标志放入队列,进程B读取队列。his不适用于此问题