多线程编程1

参考资料:

http://blog.csdn.net/JXH_123/article/details/23450031                            
秒杀多线程系列

http://www.baidu.com/index.php?tn=utf8kb_oem_dg&addresssearch=1#wd=C%2B%2B%E5%BE%AA%E7%8E%AF%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97&ie=utf-8&tn=utf8kb_oem_dg&f=8&rsv_bp=1&rsv_spt=1&rsv_n=2&rsv_sug3=32&rsv_sug4=1431&rsv_sug1=17&rsv_sug2=0&inputT=3750&bs=%E5%BE%AA%E7%8E%AF%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97           
c++消息循环队列  (没用到)

http://www.cnblogs.com/egmkang/archive/2012/11/17/2763295.html         
合理的设计与使用消息队列

http://blog.csdn.net/yand789/article/details/17095993                             
UDP多线程通信server程序

http://blog.csdn.net/no_mame/article/details/17437273                            
UDP 多线程客户端与单线程服务器端

http://so.csdn.net/search?utf8=%E2%9C%93&t=&q=+udp%E5%A4%9A%E7%BA%BF%E7%A8%8B&commit=%E6%90%9C+%E7%B4%A2&sort=                                                                                          
WaitforMultipleObjects 使用详解

http://blog.csdn.net/lyd_253261362/article/details/4450202                      
WaitforMultipleObjects 使用详解

http://bbs.csdn.net/topics/30350133                                                    
请教关于WaitforMultipleObjects的用法

http://blog.csdn.net/chw1989/article/details/7453217                              
多线程套接字编程

http://www.baidu.com/s?ie=utf-8&bs=CreateEvent&f=8&rsv_bp=1&wd=CreateEvent+%E7%94%A8%E6%B3%95%E8%AF%A6%E8%A7%A3&rsv_sug3=4&rsv_sug4=161&rsv_sug1=2&rsv_sug2=0&inputT=7745         
CreateEvent用法详解

http://www.cnblogs.com/shootingstars/archive/2004/07/15/24602.html       在主线程中慎用WaitforMultipleObjects

http://blog.sina.com.cn/s/blog_7dc67d520100t2fb.html                            
C++中queue等的使用方法

http://www.cnblogs.com/ZXYloveFR/p/3738155.html                                        
一家人的周末餐与多线程----起步

问题:如何利用多线程实现UDP多服务器端的数据的融合,并保证周期为100ms以内。

方案一:(由一朋友提供)

方案二:

/************************************************************************/

/*
程序思路:先考虑一次传输过程,利用事件内核,来同步子线程与主线程,

          利用临界区来实现锁的机制。

         
在利用事件时,我们利用自动复位事件实现,SetEvent来激活WaitForMultipleObjects,

         
当两个线程都执行完,程序执行到下一步,进入临界区,这里必须用锁,不然资源就会

          发生冲突。

         
在临界区里面,主要是obs等一些变量的清零,还有数据的求并集,以及发送操作。

         
在利用UDP发送操作时,无谓的初始化可以省略,不要多搞。
*/

/************************************************************************/

最后,利用方案二实现。

    遇到的问题:

到目前为止,我们都是等待其来临,自己去触发事件。但现实中有一难点无法处理,8线雷达,其每次都发送四层数据的信息

,需要两帧数据才可以发送数据。也就是说,八线雷达其数据周期为160ms,工作频率为12.5hz,我在想,假如我提高其频率,

将两帧数据放在八线雷达本身的客户端去处理,返回给我的还是一样的频率,这个可能会好点。提高到25hz即可。两帧数据位一周期,理论上应该可以解决这个问题。

也就是说,数据同步问题,还需要斟酌的去实现。

下面贴出代码:

.h文件 :

   1:  #ifndef NORMALNODE
   2:  #define NORMALNODE
   3:  #include <iostream>
   4:  #include <sstream>
   5:  #include <queue>
   6:  #include <Windows.h>
   7:  //socket头文件
   8:  #include "winsock.h"
   9:  //socket库的lib
  10:  #pragma comment(lib,"ws2_32.lib")
  11:  using namespace std;
  12:   
  13:  typedef unsigned short int  uint;
  14:  typedef unsigned char uchar;
  15:  #define MAXSIZE 4000     // scan data模式  获得的最多点的个数
  16:   
  17:  const UINT16 Port1 = 8060; 
  18:  const UINT16 Port2 = 8080; 
  19:   
  20:  DWORD WINAPI Child0Func(LPVOID);
  21:  DWORD WINAPI Child1Func(LPVOID);
  22:   
  23:   char szbuffer[2][2000] = {0};//缓冲区用于存放字节流数据
  24:   
  25:   const int startoffset = 4;
  26:   const int PointLength = 6;
  27:   
  28:  CRITICAL_SECTION g_csThreadCode;
  29:   
  30:  typedef struct Point        //点转换为矩阵的x与y坐标。
  31:  {
  32:      uint x;
  33:      uint y;
  34:      uchar value;
  35:      uchar U;
  36:  } Point;
  37:   
  38:  typedef struct Matrix      //稀疏矩阵数据结构
  39:  {
  40:      int Num;
  41:      Point point[MAXSIZE];
  42:   
  43:  } Matrix;
  44:   
  45:  UINT16 count1 = 0;
  46:  Matrix matrix1;
  47:  Matrix matrix2;
  48:  #endif

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

.cpp 文件:

   1:  // ThreadDemo6.cpp : 定义控制台应用程序的入口点。
   2:  //
   3:  #include "stdafx.h"
   4:  #include "Demo.h"
   5:  int _tmain(int argc, _TCHAR* argv[])
   6:  {
   7:      //初始化socket库
   8:      WSADATA wsa = {0}; //WinSockApi 取WSA+DATA组成套接字结构体
   9:      WSAStartup(MAKEWORD(2,2),&wsa);
  10:   
  11:      HANDLE hChild[4];
  12:      HANDLE hEvent[4];
  13:      DWORD threadId[4];
  14:      int obs1 = 0;
  15:      int obs2 = 0;
  16:      bool   bDone = false;
  17:   
  18:      DWORD dwStart = GetTickCount();
  19:      InitializeCriticalSection(&g_csThreadCode);
  20:      //CreateEvent创建一个事件的时候,最后一个字符串是该事件的名字,
  21:      //这样就可以在其余的地方通过这个名字来找到相应的事件了,等于是一个标识的作用 
  22:   
  23:      //第二个参数为true,所以为手动置位 。ResetEvent,使事件处于未触发状态
  24:      //一般情况下,当其处于触发状态,也就是SetEvent时,其他人可以更改
  25:      //第二个参数为false,表示自动置位,也就是不用ResetEvent。
  26:      //创建事件
  27:      hEvent[0] = CreateEventW(NULL,FALSE,FALSE,_T("ChildEvent0"));
  28:      hEvent[1] = CreateEventW(NULL,FALSE,FALSE,_T("ChildEvent1"));
  29:   
  30:      hChild[0] = CreateThread(NULL,0,Child0Func,0,0,&threadId[0]);//ID号与句柄
  31:      hChild[1] = CreateThread(NULL,0,Child1Func,0,0,&threadId[1]);
  32:   
  33:      /************************************************************************/
  34:      /*UDP部分                                                                */
  35:      /************************************************************************/
  36:      SOCKET sClient;
  37:      int iLen;  //服务器地址长度
  38:      int iSend; //接收数据的缓冲
  39:      struct sockaddr_in ser; //服务器端地址
  40:      //建立服务器端地址
  41:      ser.sin_family=AF_INET;
  42:      ser.sin_port=htons(8060);
  43:      ser.sin_addr.s_addr=inet_addr("127.0.0.1"); // 本机IP地址,测试用
  44:      //ser.sin_addr.s_addr = inet_addr("192.168.1.3");  //决策机IP地址
  45:   
  46:      //建立客户端数据报套接口
  47:      sClient=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
  48:   
  49:      if(sClient==INVALID_SOCKET)
  50:      {
  51:          printf("socket()Failed:%d\n",WSAGetLastError());
  52:          return  0;
  53:      } 
  54:      iLen=sizeof(ser);
  55:      /********************************以上是UDP发送部分程序*****************************/  
  56:   
  57:   
  58:      while(!bDone)
  59:      {    
  60:          //下面这个方法有两种状态,一个是一个个去响应事件,一个是总的去响应事件。
  61:          DWORD dwStatus = WaitForMultipleObjects(2,hEvent,TRUE,INFINITE);//infinite,不等待,setEvent可以使其返回为0
  62:          if ((dwStatus >= WAIT_OBJECT_0)&&(dwStatus <= WAIT_OBJECT_0 + 1 )   )
  63:          {
  64:              DWORD dwStart = GetTickCount();
  65:              EnterCriticalSection(&g_csThreadCode);//进入关键段  临界区
  66:              //数据处理 
  67:              UINT8 str1[2000] = {0};
  68:              UINT8 str2[2000] = {0};
  69:              //开辟两个无符号类型,这里是加了锁机制处理,string 默认并不是无符号类型
  70:              for (int i = 0; i < 2000; ++i)
  71:              {
  72:                  str1[i] = szbuffer[0][i];  
  73:                  str2[i] = szbuffer[1][i];
  74:              }
  75:              matrix1.Num = str1[3]*16*16*16 + str1[2]*16*16 + str1[1]*16 + str1[0];  
  76:              matrix2.Num = str2[3]*16*16*16 + str2[2]*16*16 + str2[1]*16 + str2[0];
  77:              for (int i = 0; i < matrix1.Num; ++i)
  78:              {
  79:                  matrix1.point[obs1].x     = str1[startoffset + 1 + i*PointLength]*16 + str1[startoffset + 0 + i*PointLength];
  80:                  matrix1.point[obs1].y     = str1[startoffset + 3 + i*PointLength]*16 + str1[startoffset + 2 + i*PointLength];
  81:                  matrix1.point[obs1].value = str1[startoffset + 4 + i*PointLength];
  82:                  matrix1.point[obs1].U     = str1[startoffset + 5 + i*PointLength];
  83:                  obs1++;  //注意清零
  84:              }
  85:              for (int i = 0; i < matrix2.Num; ++i)
  86:              {
  87:                  matrix2.point[obs2].x     = str1[startoffset + 1 + i*PointLength]*16 + str1[startoffset + 0 + i*PointLength];
  88:                  matrix2.point[obs2].y     = str1[startoffset + 3 + i*PointLength]*16 + str1[startoffset + 2 + i*PointLength];
  89:                  matrix2.point[obs2].value = str1[startoffset + 4 + i*PointLength];
  90:                  matrix2.point[obs2].U     = str1[startoffset + 5 + i*PointLength];
  91:                  obs2++;  //注意清零
  92:              }
  93:              obs1 = 0;
  94:              obs2 = 0;
  95:              Point poi;
  96:              //数据求并集然后发送
  97:              for (int i = 0; i < matrix1.Num; ++i)
  98:              {
  99:                  poi = matrix1.point[i];       //四线雷达数据集
 100:                  for (int j = 0; j < matrix2.Num; ++j)
 101:                  {
 102:                      if ((poi.x == matrix2.point[j].x) && (poi.y == matrix2.point[j].y))
 103:                      {
 104:                          matrix2.point[j] = matrix2.point[j+1];//大的替换小的
 105:                          matrix2.Num--;
 106:                          break;
 107:                      }
 108:                  }
 109:              }
 110:   
 111:              for (int i = 0; i < matrix2.Num; ++i)
 112:              {
 113:                  matrix1.point[matrix1.Num + i] = matrix2.point[i];
 114:              }
 115:              matrix1.Num = matrix1.Num + matrix2.Num;
 116:   
 117:              uint len = matrix1.Num*sizeof(Point) + 4; 
 118:              char buffer[10000];
 119:              memcpy(buffer,(char*)&matrix1,len);
 120:              iSend=sendto(sClient,buffer,len-1,0,(struct sockaddr*)&ser,iLen);
 121:              cout << "*************Total time:" << GetTickCount() - dwStart << endl;
 122:              LeaveCriticalSection(&g_csThreadCode);//离开关键段
 123:          }
 124:      }
 125:   
 126:   
 127:      for (int j = 0; j < 4; ++j)
 128:      {
 129:          CloseHandle(hEvent[j]);
 130:          CloseHandle(hChild[j]);
 131:      }
 132:      DeleteCriticalSection(&g_csThreadCode);
 133:      cout << "*************Total time:" << GetTickCount() - dwStart << endl;
 134:      return 0;
 135:  }
 136:   
 137:   
 138:  //子线程可以将主线程创建的Event激活
 139:  DWORD WINAPI Child0Func(LPVOID p) 
 140:  {
 141:      HANDLE hEvent;
 142:      hEvent = OpenEventW(EVENT_ALL_ACCESS,FALSE,_T("ChildEvent0"));
 143:      SOCKET socksvr = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
 144:      if (INVALID_SOCKET == socksvr)
 145:      {
 146:          return 0;
 147:      }
 148:      struct sockaddr_in svraddr = {0};
 149:      svraddr.sin_family = AF_INET;
 150:      svraddr.sin_port = htons(5070);
 151:      svraddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
 152:      if ( bind(socksvr,(struct sockaddr*)&svraddr,sizeof(svraddr)) == SOCKET_ERROR)//地址与套接字绑定
 153:      {
 154:          cout << "套接字绑定错误" << endl;
 155:          return 0;
 156:      }
 157:      struct sockaddr_in clientaddr = {0};
 158:      int nLen = sizeof(clientaddr);
 159:      while (true)
 160:      {
 161:          recvfrom(socksvr,(char*)szbuffer[0],2000,0,(struct sockaddr*)&clientaddr,&nLen);//构造ip地址
 162:          // cout << "flag1:  "<<count1++ <<endl;
 163:          SetEvent(hEvent); //将事件置为有信号状态,WaitForObject返回为WAIT_OBJECT_0
 164:      }
 165:  }
 166:   
 167:  //子线程可以将主线程创建的Event激活
 168:  DWORD WINAPI Child1Func(LPVOID p) 
 169:  {
 170:      HANDLE hEvent;
 171:      hEvent = OpenEventW(EVENT_ALL_ACCESS,FALSE,_T("ChildEvent1"));
 172:      SOCKET socksvr = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
 173:      if (INVALID_SOCKET == socksvr)
 174:      {
 175:          return 0;
 176:      }
 177:      struct sockaddr_in svraddr = {0};
 178:      svraddr.sin_family = AF_INET;
 179:      svraddr.sin_port = htons(5080);
 180:      svraddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
 181:      if ( bind(socksvr,(struct sockaddr*)&svraddr,sizeof(svraddr)) == SOCKET_ERROR)//地址与套接字绑定
 182:      {
 183:          cout << "套接字绑定错误" << endl;
 184:          return 0;
 185:      }
 186:      struct sockaddr_in clientaddr = {0};
 187:      int nLen = sizeof(clientaddr);
 188:      while (true)
 189:      {
 190:          recvfrom(socksvr,(char*)szbuffer[1],2000,0,(struct sockaddr*)&clientaddr,&nLen);//构造ip地址
 191:          // cout << "flag2:  "<<count1++ <<endl;
 192:          SetEvent(hEvent); //将事件置为有信号状态,WaitForObject返回为WAIT_OBJECT_0
 193:      }
 194:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

多线程编程1,布布扣,bubuko.com

时间: 2024-08-09 19:53:42

多线程编程1的相关文章

多线程编程核心技术总结(读周志明书籍的总结)

多线程编程核心技术总结 1.Java多线程基本技能 1.1进程和线程的概念: 进程是独立的程序,线程是在进程中独立运行的子任务. 1.2使用多线程 1.2.1实现方法:继承Thread类,重写Runnable接口. 1.2.2线程安全问题:并发修改公共的实例变量,i++,i-- 1.3线程Thread类的一些方法: currentThread() 放回代码段正在被那个线程调用 isAlive() 判断线程是否处于活动状态 sleep() 使得当前线程退出CPU片段,等待获取锁 1.4停止线程 1

Java基础知识—多线程编程(五)

概述 Java 给多线程编程提供了内置的支持.一个多线程程序包含两个或多个能并发运行的部分.程序的每一部分都称作一个线程,并且每个线程定义了一个独立的执行路径.使用多线程也是为了充分的利用服务器资源,提高工作效率. 线程生命周期 线程是一个动态执行的过程,它也有一个从产生到死亡的过程. 新建状态: 使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态.它保持这个状态直到程序 start() 这个线程. 就绪状态: 当线程对象调用了start()方法之后,该

第73课 Qt中的多线程编程

1. QThread类 (1)QThread是一个跨平台的多线程解决方案 (2)QThread以简洁易用的方式实现多线程编程 2. QThread中的关键成员函数 (1)virtual void run() :线程函数,用于定义线程功能(执行流). (2)void start():启动函数,将线程入口地址设置为run函数.启动线程,新线程开始执行run函数. (3)int exec():进入事件循环,直至调用exit().返回线程退出事件循环的返回码. (4)void terminate():强

多线程编程(进程和线程)

多线程编程(进程和线程) 1.进程:指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,一个进程可以启动多个线程. 2.线程:指程序中一个执行流程,一个进程中可以运行多个线程. 一.创建线程(两种方式) 二.线程的5种状态( New,Runnable,Running,Block,Dead ): 三.线程的优先级 四.守护线程 /精灵线程/后台线程 五.方法 六.同步代码锁(synchronized) 一.创建线程(两种方式): 方式1:采用继承Thread的方法 第一,继承 Thre

多线程编程基础知识

多线程编程基础知识 http://www.cnblogs.com/cy163/archive/2006/11/02/547428.html 当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软件是当今普遍采用的方法,进程和线程的概念的出现,对提高软件的并行性有着重要的意义.现在的大型应用软件无一不是多线程多任务处理,单线程的软件是不可想象的.因此掌握

iOS多线程编程

1. 进程,线程, 任务 进程:一个程序在运行时,系统会为其分配一个进程,用以管理他的一些资源. 线程:进程内所包含的一个或多个执行单元称为线程,线程一般情况下不持有资源,但可以使用其所在进程的资源. 任务:进程或线程中要做的事情. 在引入线程的操作系统中,通常把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位. 线程比进程更小,对其调度的开销小,能够提高系统内多个任务的并发执行程度. 一个程序至少有一个进程,一个进程至少有一个线程.一个程序就是一个进程,而一个程序中的多个任

多线程编程1-NSThread

前言 每个iOS应用程序都有个专门用来更新显示UI界面.处理用户触摸事件的主线程,因此不能将其他太耗时的操作放在主线程中执行,不然会造成主线程堵塞(出现卡机现象),带来极坏的用户体验.一般的解决方案就是将那些耗时的操作放到另外一个线程中去执行,多线程编程是防止主线程堵塞,增加运行效率的最佳方法. iOS中有3种常见的多线程编程方法: 1.NSThread 这种方法需要管理线程的生命周期.同步.加锁问题,会导致一定的性能开销 2.NSOperation和NSOperationQueue 是基于OC

Android多线程编程(一)——多线程基础

什么是进程 一个进程是一个独立(self contained)的运行环境,它可以看作一个程序或者一个应用. 什么是线程 而线程是进程中执行的一个任务,Java运行环境是一个包含了不同累和程序的单一进程.线程可以被称为轻量级进程.线程需要较少的资源来创建和驻留在进程中,并且可以共享进程中的资源. Android线程 Android的线程,实际上和Java的多线程编程并没有什么本质上的不同.当我们需要执行一些耗时操作,比如说发起一条网络请求时,考虑到网速等其他原因,服务器未必会立刻响应我们的请求,如

《Java多线程编程核心技术》推荐

写这篇博客主要是给猿友们推荐一本书<Java多线程编程核心技术>. 之所以要推荐它,主要因为这本书写得十分通俗易懂,以实例贯穿整本书,使得原本抽象的概念,理解起来不再抽象. 只要你有一点点Java基础,你就可以尝试去阅读它,相信定会收获甚大! 博主之前网上找了很久都没完整pdf电子版的,只有不全的试读版,这里博主提供免费.清晰.完整版供各位猿友下载: http://download.csdn.net/detail/u013142781/9452683 刚刚已经提到,<Java多线程编程核

Java多线程编程— 概念以及经常使用控制

多线程能满足程序猿编写很有效率的程序来达到充分利用CPU的目的,由于CPU的空暇时间可以保持在最低限度.有效利用多线程的关键是理解程序是并发运行而不是串行运行的.比如:程序中有两个子系统须要并发运行,这时候就须要利用多线程编程. 线程的运行中须要使用计算机的内存资源和CPU. 一.    进程与线程的概念 这两者的概念,这里仅仅给出自己狭隘的理解: 进程:进程是一个独立的活动的实体,是系统资源分配的基本单元. 它能够申请和拥有系统资源. 每一个进程都具有独立的代码和数据空间(进程上下文). 进程