求大佬来给一个“线程同步”的思路

晨易夕 2018-10-18 02:48:43
这是我一直想解决的一个问题,但我思路不清晰。

两个线程T1、T2,都运行一个死循环C1、C2。C1、C2耗时不同。
T1T2同时启动,我现在要实现无论何时查看,C1、C2循环的次数都相同。

1、现在对象锁不能实现C1C2的开头同时进行;
2、T1T2不同时启动,也需要保证C1C2的开头近乎同时进行;
3、使用情景就是两个设备的数据同步采集、即我需要两个设备近乎同一时刻的数据。
...全文
246 9 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhoujk 2018-10-19
  • 打赏
  • 举报
回复
既然可以查看,就写一点代码,让快的暂停,等一下慢的。直到下次查看到两个数据很接近了再运行。
xuzuning 2018-10-19
  • 打赏
  • 举报
回复
4.0 不支持 async await
但与之相当的是
var t = Task.Factory.StartNew(() => 方法 ); //在线程里立即执行 方法
t.Wait(); //当线程结束时,执行后续代码
var res = t.Result; //取回被执行方法的返回值(如果有的话)
或许 async await 就是上述结构的魔法术

但是前面已经说了,线程何时被执行,是不可控的
所以同时发起(从代码上看还是用顺序的)的两个线程 T1、T2,可能是 T1 先于 T2 开始工作,也可能是 T2 先于 T1 开始工作
由于线程内有外部数据交换,那么连何时结束也是未知数了

var t1 = Task.Factory.StartNew(() => 方法1 );
var t2 = Task.Factory.StartNew(() => 方法2 );
t1.Wait();
var res1 = t1.Result;
t2.Wait();
var res2 = t2.Result;
圣殿骑士18 2018-10-18
  • 打赏
  • 举报
回复
请问一下,4.0怎么操作呢。
===
p哥5楼说了:
1、一个timer,每5秒发起两个线程
2、两个线程执行数据收集,回调同一个方法,记录数据
3、在回调方法中,记录累加数,累加数是偶数时(两个线程任务已完成),发起下一次timer。
关键是每次timer任务都是启动新线程,而不是在线程中死循环!
晨易夕 2018-10-18
  • 打赏
  • 举报
回复
引用 2 楼 sp1234 的回复:
我写一个简单的 demo
using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            testc();
            Console.WriteLine("主线程结束。按任意键结束......");
            Console.ReadKey();
        }

        static async void testc()
        {
            while (true)
            {
                await Task.WhenAll(Task.Run(() =>
                 {
                     Console.WriteLine("开始执行proc1");
                     Thread.Sleep(new Random().Next(500));
                     Console.WriteLine("proc1结束");
                 }),
                 Task.Run(() =>
               {
                   Console.WriteLine("开始执行proc2");
                   Thread.Sleep(new Random().Next(500));
                   Console.WriteLine("proc2结束");
               }));
                await Task.Delay(5000);
            }
        }
    }
}
异步操作(定时操作)而已,哪有用到什么阻塞循环呢?
请问一下,4.0怎么操作呢。
  • 打赏
  • 举报
回复
你的整个程序不过就是一个定时器机制,当时间到了的时候以异步并发的方式启动两个任务去分别访问两个设备。只不过如果我们不用古老的Timer,我们可以用时髦的 Task.Delay,而已。但是这里最主要地,是步阻塞系统,不随便在当前线程浪费资源。当前动做只是注册一个委托回调定时5秒钟之后触发。所以这里的 testc 方法根本就是一个异步轮询过程,而不是一个同步死循环过程。
  • 打赏
  • 举报
回复
满脑子都是”阻塞、死循环、队列“是非常坑的低级的多线程/多进程概念,可能因为这样不用动脑筋,所以许多人都动不动就是这种思想。如果说10几年前的博客有些也许不稀奇,而现在并发编程这么普遍了,这类最初级最原始的线程使用形式也就应该逐步杜绝了。 多线程,要异步处理,每一个任务都是几毫秒、几十毫秒的短任务,任务的调用由系统线程池去调度。你用不着写什么一大堆死循环,你也用不着写什么队列去管理对象。
xuzuning 2018-10-18
  • 打赏
  • 举报
回复
T1、T2 永远都不可能同时运行,因为线程是在其他线程的间歇停顿(比如与外设交换数据)时运行的
线程在何时开始工作是不确定的,取决于操作系统的调度
  • 打赏
  • 举报
回复
我写一个简单的 demo
using System;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            testc();
            Console.WriteLine("主线程结束。按任意键结束......");
            Console.ReadKey();
        }

        static async void testc()
        {
            while (true)
            {
                await Task.WhenAll(Task.Run(() =>
                 {
                     Console.WriteLine("开始执行proc1");
                     Thread.Sleep(new Random().Next(500));
                     Console.WriteLine("proc1结束");
                 }),
                 Task.Run(() =>
               {
                   Console.WriteLine("开始执行proc2");
                   Thread.Sleep(new Random().Next(500));
                   Console.WriteLine("proc2结束");
               }));
                await Task.Delay(5000);
            }
        }
    }
}
异步操作(定时操作)而已,哪有用到什么阻塞循环呢?
  • 打赏
  • 举报
回复
线程是什么东西?专门用来死循环的?

111,097

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧