代码之家  ›  专栏  ›  技术社区  ›  TCSGrad

如何从另一个函数中的随机位置调用C函数?

  •  1
  • TCSGrad  · 技术社区  · 16 年前

    Yield() )在一个房间里的任意地方 C 函数,以便每次运行代码时, 从代码的不同部分调用?

    我面临这样一个要求,因为我在一个系统中使用了两个线程 ,其中,除非正在运行的线程显式地生成处理器,否则另一个(等待的)线程无法开始运行。我不想把这个 收益率() 在单个点调用,因为这使线程序列具有确定性。在不重新连接整个环境的情况下(从协作到先发制人),这是我能想到的唯一解决方案,线程_1()使

    我们也欢迎对实现相同最终目标的不同解决方案的任何见解!

    5 回复  |  直到 10 年前
        1
  •  3
  •   DigitalRoss    16 年前

    我认为需要一个BFI解决方案

    我认为你必须用显而易见的方法来解决这个问题。你需要为你的孩子做一个包装 Yield() 这使得一个“随机”的决定是否调用真实的东西。

    比如说:

    #define Yield0() ((random() & 0xf) == 0 && Yield())
    

    选择您想要的通话概率百分比的掩码。对于0xf,如果 random() 具有良好的低阶位随机性,那么您将在16个调用中看到1个Yield()。如果您可以使用MT或其他高质量随机数生成器,则低阶位将直接有用,否则您可能需要 random() >> 3 & ...

    您只需要将Yield0()调用放在任何地方。

        2
  •  2
  •   Jerry Coffin    16 年前

    void maybe_yield() { 
        if (rand() & 0x10)
            yield();
    }
    

    然后打电话给 maybe_yield() 0x10 设置了更多位以获取的常数 yield() srand() 值在一次运行到下一次运行时发生变化,以在不同的运行中获得不同的序列。

        3
  •  2
  •   wallyk    16 年前

    选项A:为什么不打电话 yield() 当线卡住的时候?更好的是,为什么不将其封装在每个可能卡住的操作中:

    int disk_read (...)
    {
        begin_io ();
        while (!io_completed  &&  !timed_out())
             yield();
        if (timed_out())
            // etc.
         ...
    }
    

    选项B:通常情况下,当另一个线程还没有准备好运行时, 是禁止使用的。因此,请将其放在任何地方:

    void thread1 (...)
    {
        yield();
        do_something_a();
        yield();
        do_something_b();
        yield();
        do_something_c();
        ...
    }
    

    选项C:相信处理器的速度足够快,并且等待事情发生的频率足够高,以至于最小 yields() 工作很好:

    void thread1 (...)
    {
        init();
        while (...)
        {
            do_heavy_crunching();
            yield();
            do_something_else();
        }
    }
    

    在数百个实际应用程序中,选项C可以正常工作。决定论通常是有帮助的,而不是有害的。

        4
  •  2
  •   paxdiablo    16 年前

    实际上,当您在协作线程环境中运行时,您 我想要决定论。

    但是,如果你下定决心去做,你只需要把它变成随机的。

    #include <stdlib.h>
    // And make sure you seed the generator with srand() somewhere.
    #define YIELD_CHANCE 15
    
    #define yield Yield
    #ifdef YIELD_CHANCE
        #if YIELD_CHANCE > 0
            #if YIELD_CHANCE <= 100
                #undef yield
                void yield(void) {
                    if (rand() < (RAND_MAX / (100/YIELD_CHANCE)))
                        Yield();
                    }
            #endif
        #endif
    #endif
    

    那就换衣服 Yield 呼叫 yield YIELD_CHANCE

    如果不存在或超出范围1到100, 产量 根据您给出的概率随机函数。

        5
  •  1
  •   user14554 user14554    16 年前

    你说你不想要一个预处理器,但它让它变得容易多了。

       #!/usr/bin/perl
       chomp(my $n =<stdin>);
       open (my $f, '<', $n);
       while (my $l = <$f>) {
            print $l;
            if ($l =~ /^[\s][^\.]/) {
                $r=rand();
               if ( int($r*5) == 1 ) {
                    print "\tcall Yield\n";
                }
            }
        }
    

    这个perl脚本(我的第一个)将从stdin读取一个文件名,并将一个调用随机插入到gcc-S生成的程序集中,然后可以轻松地编译该程序集。它可能不会像编译器/arch那样工作,但regex几乎可以做任何事情。

    一个很好的补充是为处理器添加一个总是在跳转指令之前的产量。这样可以节省洒布时间。最后,在跳转之前,您可以使用一个调用random()的包装器函数。