同时运行两个c#代码

3

我正在开发一个应用程序,有这样一种情况:我需要同时完成两件事,但我有点困难。我正在开发一个相机应用程序,我需要在拍照时同时触发LED灯,以获得更好的图像。以下是我尝试过的选项。

  1. Use two threads:

    Thread t1 = new Thread(
                        new ThreadStart(() =>
                        {
                            //trigger LED here
                        }));
    
    Thread t2 = new Thread(
                        new ThreadStart(() =>
                        {
                            //trigger camera
                        }));
    
    t1.Start();
    
    t2.Start();
    t1.Join();
    t2.Join();
    
  2. Trigger the light on the current thread and the camera on a separate thread

    Thread t = new Thread(
                        new ThreadStart(() =>
                        {
                            //trigger camera
                        }));
    
    // trigger LED
    t.Start();
    t.Join();
    

在这两种情况下,在大约10张图像之后,我会得到闪烁的背景,这意味着相机和LED没有同步。我的问题是,有没有办法实现我正在尝试做的事情。

谢谢。


2
没有硬件接口方法可以同时完成这两个任务吗?我猜你是在使用API与硬件通信? - Matthew Watson
正如所提到的,您需要阅读硬件/堆栈提供的API。很有可能有API可以同时激活。 - Mzf
我认为两个线程并不会更好 - 即使您设法在两个不同的处理器核心上同时运行它们(我怀疑这是不可能的,无论如何也很难控制),它们将冲突访问硬件总线,最终导致顺序激活。我想在同一个线程中依次激活一个线程会更好(或者调用是否会阻塞直到活动完成?如果有异步版本的调用,那么呢?)。 - Bob Sammers
@Matthew,Mzf:你好,相机和LED是两个不同的硬件。我通过串行调用触发LED,直接从其API调用相机。 - falopsy
@BobSammers;感谢您的帖子。这些调用不会阻塞主线程。 - falopsy
4个回答

4

如果您有两个或更多操作,可以使用以下方式并行调用它们:

Parallel.Invoke( () => DoCamera(), () => DoLighting() );

然而,这只是最好的尝试。不能保证因为毕竟你可能在一台只有一个物理处理器的机器上执行此操作,或者它正在承受重负并且只剩下10%的CPU。


@nvoigt:那你为什么要把它作为解决方案呢?它并没有做出OP的示例没有做出的任何事情(尽管它更整洁),而且他已经说过那不起作用了。 - Bob Sammers
因为这是他能得到的最好的,整个.NET框架中没有任何保证。在一台甚至不能保证有两个处理器的计算机上,没有任何软件可以保证并行性。 - nvoigt
我持不同意见 - 最好的方法是按照Bernhard Hofmann的建议更改线程优先级,并在活动发生时不阻塞,通过同一线程运行这两个调用。 - Bob Sammers

4
如果您无法在硬件层面上解决此问题,这是我在类似于Windows的非实时操作系统中能想到的最佳方法:
  1. 为这两个动作启动线程。
  2. 将它们的优先级提高到高或实时以确保它们立即启动CPU并且不受其他进程干扰。
  3. 让它们等待 Barrier。这可以确保在继续之前,这两个线程都已经开始并在障碍处进行了检查。这有助于减少定时抖动。它不能保证这两个线程同时执行其硬件操作,但它可以帮助。
如果这样仍然无法解决问题,那我也不知道还能做什么了。不过值得一试。操作系统不能保证实时执行,但是随着CPU速度达到3 GHZ以上,您可以实现惊人的实时速度。一个上下文切换可能需要3000个周期,即0.000001秒。所以您绝对可以实现极其准确的定时。

1
哇!这个工作起来像魔法一样。我相信这正是Barrier的用途:我认为不需要提高优先级(但在其他情况下可能需要,但我正在关注计算机上3个实时进程的性能损失,但在我的情况下,普通优先级已经足够好了)。程序现在已经运行了30分钟(大约1500帧,没有闪烁)。我实际上正在用1个LED同步2个摄像头,这个解决方案很好用。谢谢。 - falopsy

2
你是如何控制这两个设备(USB)的?你可能有两个物理 CPU,能够同时执行操作,但如果你的接口需要相同的通信通道,你会发现会有延迟。
此外,如果线程时间关键,你可能想提高线程的优先级。
如果你想要同步线程,你应该使用一些形式的线程同步,例如互斥锁,但除非你能保证你(和你的客户)有两个 CPU,否则最好在关键部分执行这两个操作,同时将你的线程设置为时间关键。请参见此答案以了解详细信息。

嗨Bernhard,感谢您的帖子。相机是USB设备,而LED是串行设备。我会尝试优先级的事情,并在这里报告回来。 - falopsy

0
你实际上要求的是硬件(相机触发器和LED)与编程框架之间的紧密耦合,以实现“实时”操作系统。Windows不是实时操作系统 - 微软的目标是开发一个在大多数硬件上运行的平台。
即使对于线程 - 一旦您要求CLR启动线程,也不能保证线程将在指定的时间间隔内开始运行(参考CLR via C#)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接