C 确保两个进程交错

C 确保两个进程交错,c,fork,C,Fork,在Linux上的C程序中,I fork()后跟execve()两次,以创建运行两个独立程序的两个进程。如何确保两个子进程的执行交错? 谢谢 尝试按照下面给出的答案执行上述任务,但似乎遇到sched_scheduler()进程挂起。包括下面的代码…replay1和replay2是两个程序,分别简单地打印“replay1”和“replay2” # include<stdio.h> #include <sys/types.h> #include <sys/stat.h&g

在Linux上的C程序中,I fork()后跟execve()两次,以创建运行两个独立程序的两个进程。如何确保两个子进程的执行交错? 谢谢 尝试按照下面给出的答案执行上述任务,但似乎遇到sched_scheduler()进程挂起。包括下面的代码…replay1和replay2是两个程序,分别简单地打印“replay1”和“replay2”

# include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <signal.h>
#include <sched.h>


void main()
{
 int i,pid[5],pidparent,new=0;
 char *newargv1[] = {"./replay1",NULL};
 char *newargv2[] = {"./replay2",NULL};
 char *newenviron[] = {NULL};
 struct sched_param mysched;
 mysched.sched_priority = 1;
 sched_setscheduler(0,SCHED_FIFO, &mysched);  
 pidparent =getpid();

 for(i=0;i<2;i++)
 {
   if(getpid()==pidparent)
   {
    pid[i] = fork();
    if(pid[i] != 0)
    kill(pid[i],SIGSTOP);
    if(i==0 && pid[i]==0)
     execve(newargv1[0], newargv1, newenviron);
    if (i==1 && pid[i]==0)
     execve(newargv2[0], newargv2, newenviron);       
   }
 }
for(i=0;i<10;i++)
 {
   if(new==0)
    new=1;
   else
    new=0;
   kill(pid[new],SIGCONT);
   sleep(100);
   kill(pid[new], SIGSTOP);
 }


}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
void main()
{
int i,pid[5],pid父对象,new=0;
char*newargv1[]={“/replay1”,NULL};
char*newargv2[]={“/replay2”,NULL};
char*newenviron[]={NULL};
结构sched_参数mysched;
mysched.sched_优先级=1;
sched_setscheduler(0、sched_FIFO和mysched);
pidparent=getpid();

对于(i=0;i如果您需要同步它们,并且它们是您自己的进程,请使用信号量。如果您无法访问源,则无法同步它们。

因为您需要随机交错,这里有一个可怕的方法:

  • 分叉后,立即向每个应用程序发送
    SIGSTOP
  • 使用
    sched_setscheduler
    将父应用程序设置为具有实时优先级。这将允许您使用更细粒度的计时器
  • 向其中一个子进程发送SIGCONT
  • 循环:随机短时间等待。向当前运行的应用程序发送SIGSTOP,向另一个发送SIGCONT。重复
这将有助于强制执行交错。这也将使事情变得非常缓慢。您可能还想尝试使用
sched_setaffinity
将每个进程分配给不同的CPU(如果您有双核或超线程CPU)-这将使它们有效地同时运行,以模等待I/O时间。I/O等待时间(这可能会导致他们等待硬盘,在这一点上他们可能会顺序唤醒,因此不会交错)可以通过确保他们正在处理的任何数据都在ramdisk上(在linux上,使用tmpfs)来避免


如果这对您来说过于粗粒度,您可以使用ptrace的ptrace_单步操作一次执行一个CPU操作,并根据您的需要进行交错。

如果您的目标是进行并发测试,我只知道两种技术:

  • 使用同步测试准确的场景。例如,进程1打开连接并执行查询,然后进程2进入并执行查询,然后进程1再次激活并获得结果,等等。您可以使用其他人提到的同步技术来执行此操作。但是,获得好的测试场景非常困难。我有我们过去经常使用这种方法

  • 在random you trust中:启动大量执行长时间运行的测试套件的测试进程。我在多线程和多进程测试中都使用了这种方法(我的案例是测试来自多个进程的设备驱动程序访问,而不使用蓝色屏蔽)。通常,您希望对每个流程的流程数和测试套件的迭代次数进行配置,以便您可以在发布前快速通过或进行更长时间的测试(使用10个流程运行此类测试10-12小时对我们来说并不少见)。此类测试的通常运行时间以小时为单位。您只需启动进程,让它们运行几个小时,并希望它们能够捕获所有的计时窗口。交错通常由操作系统处理,因此您不必在测试过程中担心


由于这是出于测试目的,您可以在子进程中的每一行代码之后放置
sched_yield();
调用



另一个可能的想法是让父进程
ptrace()
子进程,并使用
ptrace\u SINGLESTEP
在一条指令一条指令的基础上交错两个进程的执行。

用Bash而不是C进行作业控制要简单得多。尝试以下方法:

#! /bin/bash

stop ()
{
    echo "$1 stopping"
    kill -SIGSTOP $2
}

cont ()
{
    echo "$1 continuing"
    kill -SIGCONT $2
}

replay1 ()
{
    while sleep 1 ; do echo "replay 1  running" ; done
}

replay2 ()
{
    while sleep 1 ; do echo "replay  2 running" ; done
}

replay1 &
P1=$!
stop "replay 1" $P1

replay2 &
P2=$!
stop "replay  2" $P2

trap "kill $P1;kill $P2" EXIT

while sleep 1 ; do 
    cont "replay 1 " $P1
    cont "replay  2" $P2
    sleep 3
    stop "replay 1 " $P1
    stop "replay  2" $P2
done
这两个进程并行运行:

$ ./interleave.sh
replay 1 stopping
replay  2 stopping
replay 1  continuing
replay  2 continuing
replay  2 running
replay 1  running
replay 1  running
replay  2 running
replay 1  stopping
replay  2 stopping
replay 1  continuing
replay  2 continuing
replay 1  running
replay  2 running
replay  2 running
replay 1  running
replay  2 running
replay 1  running
replay 1  stopping
replay  2 stopping
replay 1  continuing
replay  2 continuing
replay 1  running
replay  2 running
replay 1  running
replay  2 running
replay 1  running
replay  2 running
replay 1  stopping
replay  2 stopping
^C

你到底想实现什么?让它们互相等待。这两个进程共享文件,我正在编写自己的并发解决技术,类似于数据库中的事务,我需要测试我的程序。交错应该是随机的。高优先级线程的等待时间是一个困难的值,因为它必须非常长y非常小。+1作为开场白。你可能想详细说明为什么不这样做,除了测试,tho。。但是要注意,一些最糟糕的竞争条件,特别是那些涉及恰好在两个连续cpu指令之间中断的情况,更像是一年一次或十年一次的事件。测试是好的,但不是代替审核您的并发逻辑和在纸上制定场景,您可以手动调用每个潜在的竞争情况。当然,OP在任何地方插入收益率的想法都可以通过测试发现这种十年一次的竞争……我同意。您应该同时做这两件事:分析您的并发逻辑,并做详尽的测试ting。如果你在做分析,你可以在分析的基础上创建测试用例,但是关于随机测试还有很多要说的。它们在生活中的目的是锻炼你没有想到的交互作用。哦,我知道另一种技术。使用valgrind的线程工具。当然,这不能代替对问题的正确思考。谢谢很多..按照建议进行了尝试,我将我的代码作为问题的编辑。sched_setscheduler()似乎挂起了进程。非常感谢您的帮助。@Lipika,我建议的操作顺序很重要-您在分叉之前设置了FIFO调度程序,这意味着子进程将是实时的,除非它休眠,否则父进程可能再也没有机会运行了。再次感谢..但我认为问题出在我的进程上不是特权流程,因此无法更改pri