在Linux上的C程序中,我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);
}
}
答案 0 :(得分:3)
由于你需要随机交错,所以这是一个可怕的黑客攻击:
SIGSTOP
。sched_setscheduler
的实时优先级。这将允许您拥有更细粒度的计时器。这将有助于强制执行交错。它也会让事情变得很慢。您可能还想尝试使用sched_setaffinity
将每个进程分配给不同的CPU(如果您有双核或超线程CPU) - 这将使它们有效地同时运行,模数I / O的等待时间。 I / O等待时间(这可能导致它们等待硬盘,此时它们可能会顺序唤醒并因此不会交错)可以通过确保它们正在操作的任何数据在ramdisk上来避免(在linux上,使用tmpfs)。
如果这对您来说太粗糙,您可以使用ptrace的PTRACE_SINGLESTEP操作一次执行一个CPU操作,并根据需要进行交错。
答案 1 :(得分:2)
由于这是出于测试目的,您可以在子进程中的每行代码之后放置sched_yield();
次调用。
另一个可能的想法是让子进程ptrace()
进行处理,并使用PTRACE_SINGLESTEP
逐个指令地交错两个进程的执行。
答案 2 :(得分:1)
如果您需要同步它们并且它们是您自己的进程,请使用信号量。如果您无权访问源,则无法同步它们。
答案 3 :(得分:0)
如果你的目标是进行并发测试,我只知道两种技术:
使用同步测试确切的方案。例如,进程1打开一个连接并执行查询,然后进程2进入并执行查询,然后process1再次激活并获取结果等。您可以使用其他人提到的同步技术来执行此操作。但是,获得良好的测试场景非常困难。我过去很少使用这种方法。
随意相信:启动执行长时间运行的测试套件的大量测试进程。我将这种方法用于多线程和多进程测试(我的情况是测试来自多个进程的设备驱动程序访问而不进行蓝屏筛选)。通常,您希望每个进程可以配置测试套件的进程数和迭代次数,以便您可以在发布之前快速通过或进行更长时间的测试(运行此类测试,10个进程为10-12)小时对我们来说并不罕见)。这种测试的常规运行以小时为单位。你只需启动进程,让它们运行几个小时,并希望它们能够捕获所有的时间窗口。交错通常由操作系统处理,因此您不必在测试过程中担心它。
答案 4 :(得分:0)
使用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