本文作为 .Net 并行计算 的第二篇

  • 名词解释

任务并行是指一个或者多个独立的任务同时运行。任务并行类似于多线程或者ThreadPool 工作项。但是抽象的级别更高

  • 并行任务的2个有点 1。系统使用的率更高 2.可以使用更多的编程控件
  • 创建和运行任务

1.隐式创建和运行任务。Parallel.Invoke方法提供了一种简便方式,可同时运行任意数量的任意语句。只需为每个工作项传入 Action 委托即可 大家可以想一下了例子的运行结果是什么? 会是输出 时间2000 吗 。如果你这么想就错了。笔者的电脑上输出的结果为 时间1005 (可能在你的电脑上的结果和我的不一定相同)因为他并不是一个顺序执行的过程。

1
2
Stopwatch watch1 = Stopwatch.StartNew();<br>            Parallel.Invoke(() => { Thread.Sleep(1000); }, () => { Thread.Sleep(1000); });
Console.WriteLine("时间"+watch1.ElapsedMilliseconds);

2.显示创建和运行任务

不返回值的任务由 System.Threading.Tasks.Task 类表示。返回值的任务由 System.Threading.Tasks.Task<TResult>类表示,该类从Task继承任务对象处理基础结构详细信息,并提供可在任务的整个生存期内从调用线程访问的方法和属性。下面的例子演示创建一个不返回的任务,和一个返回值的任务

            var task = new Task(() => { Thread.Sleep(1000); });
task.Start();
var task1 = new Task<int>(() => { Thread.Sleep(1000); return 100; });
task1.Start();
Console.WriteLine(task1.Result);
Console.ReadLine();
  • 延续任务

我们经常会面对这样一个场景。在一个操作完成后调用另一个的操作并将结果传递其中,我们日常编程中我们一般使用回调来弄。那么我们要怎么样在并行中来处理这个场景了。并行库中的“延续任务”提供了同样功能。  延续任务是一个异步任务,由另一个任务(称为前面的任务)在完成时调用。  下面的例子将使用TaskA.ContinueWith演示创建延续

            Task<int> TaskA = new Task<int>(() => { return DateTime.Now.Year; });
Task<String> TaskB = TaskA.ContinueWith((a) => { return String.Format("今年是{0}年", a.Result); });
TaskA.Start();
Console.WriteLine(TaskB.Result);

在上面这个例子中TaskB 必须要TaskA 完成之后。才能得到正确结果。这只是延续的一个非常简单的例子,当然你也可以创建一个多任务延续你可以在多个,或者全部的任务完成之后来运行 这里我还是以上面的取消年月为例子给大家演示一下

   Task<int>[] tasks = new Task<int>[2];
tasks[0]= new Task<int>(() => { return DateTime.Now.Year; });
tasks[1] = new Task<int>(() => { return DateTime.Now.Month; });
var continuation = Task.Factory.ContinueWhenAll(
tasks,
(antecedents) =>
{
string r = string.Format("现在是{0}年{1}月", antecedents[0].Result, antecedents[1].Result);
Console.WriteLine(r);
});
tasks[0].Start();
tasks[1].Start();
continuation.Wait();
  • 嵌套任务和子任务

子任务(或嵌套任务)是在另一个任务(称为父任务)的用户委托中创建的Task实例。 子任务可分离或附加。  分离的子任务是独立于其父任务执行的任务。  附属子任务是使用 TaskCreationOptions.AttachedToParent 选项创建的嵌套任务。  一个任务可以创建任意数量的嵌套和分离子任务,该数量仅受系统资源限制

 var parent = Task.Factory.StartNew(() =>
{
Console.WriteLine("父任务"); var child = Task.Factory.StartNew(() =>
{ Thread.Sleep(5000);
Console.WriteLine("子任务");
});
}); parent.Wait();
Console.WriteLine("大家都完了.");

大家想不想知道,上面的执行结果是怎么样了 "父任务 子任务 大家都完了" 还是“父任务  大家都完了 子任务" 你可以把这段代码考到vs中,你就会发现是后者从上面的例子中我们可以得出以下结论 父任务是不等待子任务完成的  他还有以下特性 父任务不传播子任务引发的异常。父级状态不依赖于子状态。

  • 任务取消

1.简单从委托中返回。其实在多数情况下这样已经够了。但是这样取消的任务实例不会转为Canceled状态而是转为RanToCompletion状态

2.引发 OperationCanceledException

           var tokenSource = new CancellationTokenSource();
CancellationToken ct = tokenSource.Token; var task = Task.Factory.StartNew(() =>
{
ct.ThrowIfCancellationRequested(); bool moreToDo=true;
while (moreToDo)
{
if (ct.IsCancellationRequested)
{
ct.ThrowIfCancellationRequested();
}
} }, tokenSource.Token); tokenSource.Cancel();
try
{
task.Wait();
}
catch (AggregateException e)
{
foreach (var v in e.InnerExceptions)
Console.WriteLine(e.Message + " " + v.Message);
}

下一篇将讲一下并行Linq 欢迎交流拍砖

WinSocket同时接入量的疑惑(求解...)

在写TCP应用的时候一般都通过Accept来接入连接的接入,但对于Socket来说这个Accept同时能处理多大的量一般都没有明确说明,在应用中主要根据自己的需要设置Listen的队列数量.那Listen(1000)是不是就能说明同时刻1000个连接进来都能被Accept到呢?通过测试的结果来看windows下是不能的....Linux下则可以.

测试代码

  • C#

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Socket mSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    mSocket.Bind(new IPEndPoint(IPAddress.Any,80));
    mSocket.Listen(1000);
    int i = 0;
    while (true)
    {
        Socket http= mSocket.Accept();
        System.Threading.Thread.Sleep(200);
        i++;
        Console.WriteLine("Accept:{0} ", i);
         
    }
  • win C++
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    iResult = listen(ListenSocket, 1000);
    if (iResult == SOCKET_ERROR) {
        printf("listen failed with error: %d\n", WSAGetLastError());
        closesocket(ListenSocket);
        WSACleanup();
        return 1;
    }
    int i=0;
    while(true)
    {
        // Accept a client socket
        ClientSocket = accept(ListenSocket, NULL, NULL);
        i++;
        if (ClientSocket == INVALID_SOCKET) {
            printf("accept failed with error: %d\n", WSAGetLastError());
            closesocket(ListenSocket);
            WSACleanup();
            return 1;
        }
        iResult = recv(ClientSocket, recvbuf, recvbuflen, 0);
        printf("accept: %d\n", i);  
    }
  • linux c++
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    if (bind(server_sockfd,(struct sockaddr *)&my_addr,sizeof(struct sockaddr))<0)
    {
        perror("bind");
        return 1;
    }
    listen(server_sockfd,1000);
    sin_size=sizeof(struct sockaddr_in);
    int i=0;
    while(1)
    {
        i++;
        if((client_sockfd=accept(server_sockfd,(struct sockaddr *)&remote_addr,&sin_size))<0)
        {
            cout<<"accept error";
            return 1;
        }
         len=recv(client_sockfd,buf,BUFSIZ,0);
        cout << "Accept:" << i<<"Receive:"<<len;
     
    }

通过AB开启500个用户压相应的程序,C#,WIN C++都会导致AB出现apr_socket_recv: Connection refused (111).但Linux c++这代码是完全正常,AB所有请求的连接都通过被Linux c++接入.

以上程序上所有Listen都是1000, 按理500个用户同时接入不应该存在被拒绝的情况,因为请求的连接数并没达队列溢出的情况.但测试的结果很明确地说明的问题所在,winsocket下无法同时接入这个量的连接,其实在测试过程250个用户同时接入winsocket就存在拒绝接入的情况,当然服务是不会有影响只是有些连接无法被接入.

总结

通过测试可以确认是winsocket的限制,windows则没有因为IIS是可以抵抗这么多用户同时接入的.其实对于普通服务来说同时200个用户接入已经是一个不小的量了,因为持续这个量的处理每秒接入量可以达到1-2W.但感觉奇怪的是为什么Listen(1000)在winsocket下没有起到作用呢?找了很多资料都没找到具体原因,如果有熟悉winsocket还有其他参数设置的话希望能分享一下...

 
 
分类: .Net

TCP应用的更多相关文章

  1. Tcp/ip 报文解析

    在编写网络程序时,常使用TCP协议.那么一个tcp包到底由哪些东西构成的呢?其实一个TCP包,首先需要通过IP协议承载,而IP报文,又需要通过以太网传送.下面我们来看看几种协议头的构成 一 .Ethe ...

  2. C#高性能TCP服务的多种实现方式

    哎~~ 想想大部分园友应该对 "高性能" 字样更感兴趣,为了吸引眼球所以标题中一定要突出,其实我更喜欢的标题是<猴赛雷,C#编写TCP服务的花样姿势!>. 本篇文章的主 ...

  3. Android实现TCP断点上传,后台C#服务实现接收

    终端实现大文件上传一直都是比较难的技术,其中涉及到后端与前端的交互,稳定性和流量大小,而且实现原理每个人都有自己的想法,后端主流用的比较多的是Http来实现,因为大多实现过断点下载.但稳定性不能保证, ...

  4. 漫谈TCP

    不得不承认,tcp是一个非常复杂的协议.它包含了RFC793及之后的一些协议.能把tcp的所有方面面面具到地说清楚,本身就是个很复杂的事情.如果再讲得枯燥,那么就会更让人昏昏欲睡了.本文希望能尽量用稍 ...

  5. 高性能 TCP/UDP/HTTP 通信框架 HP-Socket v4.1.1

    HP-Socket 是一套通用的高性能 TCP/UDP/HTTP 通信框架,包含服务端组件.客户端组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP/HTTP 通信系统,提供 C/ ...

  6. TCP/IP基础

    TCP/IP 是用于因特网 (Internet) 的通信协议. 计算机通信协议是对那些计算机必须遵守以便彼此通信的规则的描述. 什么是 TCP/IP? TCP/IP 是供已连接因特网的计算机进行通信的 ...

  7. TCP/IP之TCP_NODELAY与TCP_CORK

    TCP/IP之Nagle算法与40ms延迟提到了Nagle 算法.这样虽然提高了网络吞吐量,但是实时性却降低了,在一些交互性很强的应用程序来说是不允许的,使用TCP_NODELAY选项可以禁止Nagl ...

  8. TCP/IP之Nagle算法与40ms延迟

    Nagle算法是针对网络上存在的微小分组可能会在广域网上造成拥塞而设计的.该算法要求一个TCP连接上最多只能有一个未被确认的未完成的小分组,在该分组确认到达之前不能发送其他的小分组.同时,TCP收集这 ...

  9. TCP的数据传输小结

    TCP的交互数据流 交互式输入 通常每一个交互按键都会产生一个数据分组,也就是说,每次从客户传到服务器的是一个字节的按键(而不是每次一行) 经受时延的确认 通常TCP在接受到数据时并不立即发送ACK: ...

  10. TCP服务和首部知识点小结

    服务 应用程序会被TCP分割成数据段,而UDP不分割. TCP有超时重传和确认 如果检验和出错将丢弃 IP数据包可能会失序或者重复,所以TCP会处理 滑动窗口来进行流量控制 对字节流的内容不做任何解释 ...

随机推荐

  1. Visual Studio Code开发TypeScript

    [Tool] 使用Visual Studio Code开发TypeScript   [Tool] 使用Visual Studio Code开发TypeScript 注意 依照本篇操作步骤实作,就可以在 ...

  2. React.js初探(一)

    前端框架多如牛毛的今天,团队的技术选型很重要,没有最好的,只有最合适的,这话早已经被说烂了. 但是作为一个有追求的前端,对新技术的敏感以及尝试心理还是要有的. 虽然React已经火的不行了,但由于自己 ...

  3. form表单target的用法,实现无刷新提交页面

    form表单的target,当将iframe设置为隐藏时,可以实现当前页表单提交而不进行跳转刷新.代码如下,首页在页面里准备一个form表单和一个iframe. <form action=&qu ...

  4. elasticsearch的rest搜索--- 安装

    目录: 一.针对这次装B 的解释 二.下载,安装插件elasticsearch-1.7.0   三.索引的mapping 四. 查询 五.对于相关度的大牛的文档 二.安装   1. 安装head管理插 ...

  5. 【高德地图API】如何获得行政区域?如何制作行政规划图?

    原文:[高德地图API]如何获得行政区域?如何制作行政规划图? 什么是行政规划图?如何获得每个行政区域的边界轮廓图?举例:重庆市 江北区.如图: 官方类参考:http://developer.amap ...

  6. 【高德地图API】那些年我们一起开发的APP—即LBS应用模式分享

    原文:[高德地图API]那些年我们一起开发的APP—即LBS应用模式分享 摘要:利用地图API都能做些什么应用呢?应用商店里所有的分类,都可以结合上LBS来丰富应用.除了传统的生活服务应用,还有新潮的 ...

  7. Django教程汇总

    Django基础教程 被解放的姜戈01 初试天涯 被解放的姜戈02 庄园疑云 被解放的姜戈03 所谓伊人 被解放的姜戈04 各取所需 被解放的姜戈05 黑面管家 被解放的姜戈06 假作真时 Djang ...

  8. Warning: Cannot modify header information - headers already sent by (output started at

    一般来说在header函数前不能输出html内容,类似的还有setcookie() 和 session 函数,这些函数需要在输出流中增加消息头部信息.如果在header()执行之前有echo等语句,当 ...

  9. SQL点滴30—SQL中常用的函数

    原文:SQL点滴30-SQL中常用的函数 该文章转载自http://www.cnblogs.com/jiajiayuan/archive/2011/06/16/2082488.html 别人的总结,很 ...

  10. Cocos2d-x3.0 Json解析

    2dx3.0下一个JSON解析库官员以及集成.我们参考一下吧OK. JSON文件hello.json内容 {"pets":["dog","cat&qu ...