VC 多线程编写

  1. #include <windows.h>  
  2. #include <iostream.h>  
  3.   
  4. DWORD WINAPI fun1(LPVOID lpParameter);  
  5. DWORD WINAPI fun2(LPVOID lpParameter);  
  6.   
  7.   
  8. int tickets = 100;  
  9. CRITICAL_SECTION g_cs;  
  10.   
  11. void main()  
  12. {  
  13.   
  14.     HANDLE hThread1;  
  15.     HANDLE hThread2;  
  16.   
  17.     hThread1 = CreateThread(NULL,0,fun1,NULL,0,NULL);  
  18.     hThread2 = CreateThread(NULL,0,fun2,NULL,0,NULL); //第四个参数可以来传递变量从主线程进入到fun线程。  
  19.     CloseHandle(hThread1);//关掉线程句柄,不是关掉线程本身。  
  20.     CloseHandle(hThread2);  
  21.       
  22.     InitializeCriticalSection(&g_cs);  
  23.   
  24.     Sleep(1000);  
  25.   
  26.     DeleteCriticalSection(&g_cs);  
  27. }  
  28.   
  29. DWORD WINAPI fun1(LPVOID IpParameter)  
  30. {  
  31.   
  32.     while(TRUE)  
  33.     {  
  34.   
  35.         EnterCriticalSection(&g_cs);  
  36.         if (tickets >0)    
  37.         {  
  38.             cout<<"thread1 sell ticket : "<<tickets--<<endl;  
  39.             LeaveCriticalSection(&g_cs);  
  40.         }  
  41.         else   
  42.         {  
  43.             break;  
  44.             LeaveCriticalSection(&g_cs);  
  45.         }  
  46.   
  47.     }  
  48.       
  49.     return 0;  
  50. }  
  51.   
  52. DWORD WINAPI fun2(LPVOID IpParameter)  
  53. {  
  54.   
  55.     while(TRUE)  
  56.     {  
  57.         EnterCriticalSection(&g_cs);  
  58.   
  59.         if (tickets >0)    
  60.         {  
  61.             cout<<"thread2 sell ticket : "<<tickets--<<endl;  
  62.             LeaveCriticalSection(&g_cs);  
  63.         }  
  64.         else   
  65.         {  
  66.             break;  
  67.             LeaveCriticalSection(&g_cs);  
  68.         }  
  69.   
  70.     }  
  71.     return 0;  
  72. }  



如上程序,在主线程里面定义两个线程,分别从fun1和fun2开始执行。线程是利用时间片来共享一个CPU时间的,因为CPU运行速度够快,所以我们认为两个线程是并行执行的。然后利用关键代码段来实现进程互斥。对于一个全局变量来说,在各个进程中都有被用到,需要在A进程用到的时候,其他进程不能使用,不然变量就乱了。

在A进程中使用

EnterCriticalSection(&g_cs);
进入关键代码段,当其他进程遇到同样的EnterCriticalSection(&g_cs);时候,会等待g_cs的释放。所以其他进程就进入等待状态。
然后A进程使用完全局变量。释放g_cs
LeaveCriticalSection(&g_cs);



用VC MFC写的一个使用socket接受图片,然后显示图片两个进程。

其中使用一个ALL_BUFFER结构的全局变量来连接两个进程,使用关键代码段来保持这两个进程的互斥。

ALL_BUFFER结构中有100个指向char的指针,当然这个100可以更改。

当接受到图片后,把当前图片保存在的buffer复制到ALL_BUFFER的第一个指针去,然后来更多就都存进去。

然后另外一个线程从这个ALL_BUFFER中取出buffer显示出来。

所以简单来说就是一个线程只管接受,一个线程只管显示。公用一个char*型的数组(栈)。

这也达到了数据缓存的效果。



[cpp]  view plain copy
  1. // Client_MuliThereadDlg.h : header file  
  2. //  
  3. #pragma once  
  4.   
  5.   
  6. struct RECVPARAM  
  7. {  
  8.     SOCKET sock;  
  9.     HWND hwnd;  
  10. };  
  11. struct a_buffer_size  
  12. {  
  13.     char* a_buffer;  
  14.     int size;  
  15. };  
  16. struct ALL_BUFFER    
  17. {  
  18.     a_buffer_size ABUFFERSIZE[100];  
  19.     int bufferPos;  
  20.   
  21.     ALL_BUFFER()  
  22.     {  
  23.         bufferPos = 0;  
  24.     }  
  25. };  
  26.   
  27.   
  28. // CClient_MuliThereadDlg dialog  
  29. class CClient_MuliThereadDlg : public CDialog  
  30. {  
  31. // Construction  
  32. public:  
  33.     CClient_MuliThereadDlg(CWnd* pParent = NULL);   // standard constructor  
  34.   
  35. // Dialog Data  
  36.     enum { IDD = IDD_CLIENT_MULITHEREAD_DIALOG };  
  37.   
  38.     protected:  
  39.     virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support  
  40.   
  41.   
  42. // Implementation  
  43. protected:  
  44.     HICON m_hIcon;  
  45.   
  46.     // Generated message map functions  
  47.     virtual BOOL OnInitDialog();  
  48.     afx_msg void OnPaint();  
  49.     afx_msg HCURSOR OnQueryDragIcon();  
  50.     DECLARE_MESSAGE_MAP()  
  51. public:  
  52.     afx_msg void OnBnClickedOk();  
  53. public:  
  54.     BOOL InitSock(void);  
  55.   
  56. private:  
  57.     SOCKET m_socket;  
  58.   
  59. public:  
  60.     static DWORD WINAPI CClient_MuliThereadDlg::dataRecv(LPVOID IpParameter);  
  61. public:  
  62.     static DWORD WINAPI CClient_MuliThereadDlg::dataDisp(LPVOID IpParameter);  
  63. };  



[cpp]  view plain copy
  1. // Client_MuliThereadDlg.cpp : implementation file  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include "Client_MuliTheread.h"  
  6. #include "Client_MuliThereadDlg.h"  
  7.   
  8. #ifdef _DEBUG  
  9. #define new DEBUG_NEW  
  10. #endif  
  11.   
  12.   
  13.   
  14.   
  15. // CClient_MuliThereadDlg dialog  
  16. //int maxBuffer = 10240000;  
  17. CRITICAL_SECTION g_cs;  
  18. ALL_BUFFER aBuffer;  
  19.   
  20.   
  21. CClient_MuliThereadDlg::CClient_MuliThereadDlg(CWnd* pParent /*=NULL*/)  
  22.     : CDialog(CClient_MuliThereadDlg::IDD, pParent)  
  23. {  
  24.     m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);  
  25. }  
  26.   
  27. void CClient_MuliThereadDlg::DoDataExchange(CDataExchange* pDX)  
  28. {  
  29.     CDialog::DoDataExchange(pDX);  
  30. }  
  31.   
  32. BEGIN_MESSAGE_MAP(CClient_MuliThereadDlg, CDialog)  
  33.     ON_WM_PAINT()  
  34.     ON_WM_QUERYDRAGICON()  
  35.     //}}AFX_MSG_MAP  
  36. END_MESSAGE_MAP()  
  37.   
  38.   
  39. // CClient_MuliThereadDlg message handlers  
  40.   
  41.   
  42. BOOL CClient_MuliThereadDlg::OnInitDialog()  
  43. {  
  44.     CDialog::OnInitDialog();  
  45.   
  46.     // Set the icon for this dialog.  The framework does this automatically  
  47.     //  when the application's main window is not a dialog  
  48.     SetIcon(m_hIcon, TRUE);         // Set big icon  
  49.     SetIcon(m_hIcon, FALSE);        // Set small icon  
  50.   
  51.     // TODO: Add extra initialization here  
  52.     InitSock();  
  53.     RECVPARAM *pRecvParam1 = new RECVPARAM;  
  54.     RECVPARAM *pRecvParam2 = new RECVPARAM;  
  55.     pRecvParam1->sock =m_socket;  
  56.     pRecvParam1->hwnd =m_hWnd;  
  57.     pRecvParam2 = pRecvParam1;  
  58.     HANDLE mThread1 = CreateThread(NULL,0,dataRecv,(LPVOID)pRecvParam1,0,NULL);  
  59.     HANDLE mThread2 = CreateThread(NULL,0,dataDisp,(LPVOID)pRecvParam2,0,NULL);  
  60.     CloseHandle(mThread1);  
  61.     CloseHandle(mThread2);  
  62.     InitializeCriticalSection(&g_cs);  
  63.     return TRUE;  // return TRUE  unless you set the focus to a control  
  64. }  
  65.   
  66. // If you add a minimize button to your dialog, you will need the code below  
  67. //  to draw the icon.  For MFC applications using the document/view model,  
  68. //  this is automatically done for you by the framework.  
  69.   
  70. void CClient_MuliThereadDlg::OnPaint()  
  71. {  
  72.     if (IsIconic())  
  73.     {  
  74.         CPaintDC dc(this); // device context for painting  
  75.   
  76.         SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);  
  77.   
  78.         // Center icon in client rectangle  
  79.         int cxIcon = GetSystemMetrics(SM_CXICON);  
  80.         int cyIcon = GetSystemMetrics(SM_CYICON);  
  81.         CRect rect;  
  82.         GetClientRect(&rect);  
  83.         int x = (rect.Width() - cxIcon + 1) / 2;  
  84.         int y = (rect.Height() - cyIcon + 1) / 2;  
  85.   
  86.         // Draw the icon  
  87.         dc.DrawIcon(x, y, m_hIcon);  
  88.     }  
  89.     else  
  90.     {  
  91.         CDialog::OnPaint();  
  92.     }  
  93. }  
  94.   
  95. // The system calls this function to obtain the cursor to display while the user drags  
  96. //  the minimized window.  
  97. HCURSOR CClient_MuliThereadDlg::OnQueryDragIcon()  
  98. {  
  99.     return static_cast<HCURSOR>(m_hIcon);  
  100. }  
  101.   
  102.   
  103. void CClient_MuliThereadDlg::OnBnClickedOk()  
  104. {  
  105.     // TODO: Add your control notification handler code here  
  106.     DeleteCriticalSection(&g_cs);  
  107.     OnOK();  
  108. }  
  109.   
  110.   
  111.   
  112. BOOL CClient_MuliThereadDlg::InitSock(void)  
  113. {  
  114.     WSADATA wsaData;  
  115.     int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );  
  116.   
  117.   
  118.     //SOCKET m_socket;  
  119.     m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );  
  120.   
  121.   
  122.     sockaddr_in service;  
  123.   
  124.     service.sin_family = AF_INET;  
  125.     service.sin_addr.s_addr = inet_addr("163.180.117.229");  
  126.     service.sin_port = htons( 6000 );  
  127.     if ( bind( m_socket, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR ) {  
  128.         closesocket(m_socket);  
  129.         return FALSE;  
  130.     }  
  131.     listen( m_socket, SOMAXCONN );  
  132.     return TRUE;  
  133. }  
  134.   
  135. DWORD WINAPI CClient_MuliThereadDlg::dataRecv(LPVOID IpParameter)  
  136. {  
  137.     SOCKET sock = ((RECVPARAM*)IpParameter)->sock;  
  138.     //HWND hwnd = ((RECVPARAM*)IpParameter)->hwnd;  
  139.     //HDC hdc = ::GetDC(hwnd);  
  140.     SOCKET AcceptSocket;  
  141.   
  142.   
  143.     SOCKADDR_IN serverInfo;  
  144.     int len = sizeof(SOCKADDR);  
  145.   
  146.     AcceptSocket = accept(sock , (SOCKADDR*)&serverInfo, &len);  
  147.   
  148.   
  149.     int flag = 1;  
  150.   
  151.     int PackteSize = 1024;  
  152.     int PacketCount,LastDataPacket;  
  153.     int lSzie;  
  154.   
  155.     char* recvbuf;  
  156.     char* buffer_last;  
  157.     char* buffer;  
  158.     char recvbuf_count[10];  
  159.     char recvbuf_last[6];  
  160.     char temp[10];  
  161.     int pos;  
  162.     int bytesRecv,num;  
  163.     int bytesRecv_count,bytesRecv_last;  
  164.   
  165.       
  166.   
  167. //  int test;  
  168.     int pos_temp;  
  169.     recvbuf = (char*)malloc(sizeof(char)*(PackteSize+10));  
  170.   
  171.     while(1)  
  172.     {  
  173.   
  174.         bytesRecv_count = recv(AcceptSocket,recvbuf_count,10,0);  
  175.         if ( bytesRecv_count == 0 )  
  176.             break;  
  177.   
  178.         PacketCount = atoi(recvbuf_count);  
  179.   
  180.         //receive the LastDataPacket  
  181.         bytesRecv_last = recv(AcceptSocket,recvbuf_last,6,0);  
  182.   
  183.         LastDataPacket = atoi(recvbuf_last);  
  184.   
  185.         lSzie = PackteSize * PacketCount + LastDataPacket;  
  186.   
  187.   
  188.   
  189.         buffer_last = (char*)malloc(sizeof(char)*(LastDataPacket+10));  
  190.   
  191.   
  192.         buffer = (char*)malloc(sizeof(char)*lSzie);  
  193.   
  194.   
  195.         int iRecvSize;  
  196.         int iRet;  
  197.         int idx;  
  198.   
  199.         int i;  
  200.         for (i=0;i<PacketCount;i++)  
  201.         {  
  202.             iRecvSize = PackteSize + 10;  
  203.             idx = 0;  
  204.             while (iRecvSize > 0)  
  205.             {  
  206.                 iRet = recv(AcceptSocket, recvbuf+idx, iRecvSize, 0);  
  207.                 if (iRet > 0)  
  208.                 {  
  209.                     idx += iRet;  
  210.                     iRecvSize -= iRet;  
  211.                 }  
  212.                 else if (iRet == 0)  
  213.                 {  
  214.                     break;  
  215.                 }  
  216.                 else if ( iRet == SOCKET_ERROR)  
  217.                 {  
  218.                     break;  
  219.                 }  
  220.             }  
  221.   
  222.             memcpy(temp,recvbuf,10);  
  223.             pos = atoi(temp);  
  224.   
  225.             memcpy(buffer+pos,recvbuf+10,PackteSize);  
  226.         }  
  227.         iRecvSize = LastDataPacket + 10;  
  228.         idx = 0;  
  229.         while (iRecvSize > 0)  
  230.         {  
  231.             iRet = recv(AcceptSocket, buffer_last+idx, iRecvSize, 0);  
  232.             if (iRet > 0)  
  233.             {  
  234.                 idx += iRet;  
  235.                 iRecvSize -= iRet;  
  236.             }  
  237.             else if (iRet == 0)  
  238.             {  
  239.                 break;  
  240.             }  
  241.             else if ( iRet == SOCKET_ERROR)  
  242.             {  
  243.                 break;  
  244.             }  
  245.         }  
  246.   
  247.         memcpy(temp,buffer_last,10);  
  248.         pos = atoi(temp);  
  249.         memcpy(buffer+pos,buffer_last+10,LastDataPacket);  
  250.   
  251.         EnterCriticalSection(&g_cs);  
  252.         pos_temp = aBuffer.bufferPos;  
  253.         aBuffer.ABUFFERSIZE[pos_temp].a_buffer = (char*)malloc(sizeof(char)*lSzie);  
  254.         memcpy(aBuffer.ABUFFERSIZE[pos_temp].a_buffer,buffer,lSzie);  
  255.         aBuffer.ABUFFERSIZE[pos_temp].size = lSzie;  
  256.         aBuffer.bufferPos++;  
  257.         LeaveCriticalSection(&g_cs);  
  258.   
  259.   
  260.   
  261.   
  262.   
  263.         free(buffer_last);  
  264.         free(buffer);  
  265.     }  
  266.   
  267.   
  268.     free(recvbuf);  
  269.       
  270.       
  271.   
  272.   
  273.     closesocket(AcceptSocket);  
  274.   
  275.     WSACleanup();  
  276.   
  277.       
  278.     return 0;  
  279. }  
  280.   
  281. DWORD WINAPI CClient_MuliThereadDlg::dataDisp(LPVOID IpParameter)  
  282. {  
  283.     HWND hwnd = ((RECVPARAM*)IpParameter)->hwnd;  
  284.     HDC hdc = ::GetDC(hwnd);  
  285.   
  286.     IPicture* pPic;  
  287.     IStream* pStm;  
  288.   
  289.     int pos_temp;  
  290.     int lSzie;  
  291.     char* buffer;  
  292.   
  293.     while(TRUE)  
  294.     {  
  295.         EnterCriticalSection(&g_cs);  
  296.         if (aBuffer.bufferPos > 0)  
  297.         {  
  298.               
  299.             pos_temp = aBuffer.bufferPos;  
  300.             lSzie = aBuffer.ABUFFERSIZE[pos_temp-1].size;  
  301.             buffer = (char*)malloc(sizeof(char)*lSzie);  
  302.             memcpy(buffer,aBuffer.ABUFFERSIZE[pos_temp-1].a_buffer,lSzie);            
  303.             aBuffer.bufferPos--;  
  304.             free(aBuffer.ABUFFERSIZE[pos_temp-1].a_buffer);  
  305.   
  306.             LeaveCriticalSection(&g_cs);  
  307.   
  308.   
  309.             HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE,lSzie);  
  310.             LPVOID pvData = NULL;  
  311.             pvData = GlobalLock(hGlobal);  
  312.             memcpy(pvData,buffer,lSzie);  
  313.             GlobalUnlock(hGlobal);  
  314.             CreateStreamOnHGlobal(hGlobal,TRUE,&pStm);  
  315.             ULARGE_INTEGER  pSeek;  
  316.             LARGE_INTEGER  dlibMove  ={0};  
  317.             pStm->Seek(dlibMove,STREAM_SEEK_SET,&pSeek);  
  318.             OleLoadPicture(pStm,lSzie,TRUE,IID_IPicture,(LPVOID*)&pPic);  
  319.   
  320.   
  321.             OLE_XSIZE_HIMETRIC hmWidth;   
  322.             OLE_YSIZE_HIMETRIC hmHeight;   
  323.             pPic->get_Width(&hmWidth);  
  324.             pPic->get_Height(&hmHeight);  
  325.             pPic->Render(hdc,0,0,320,240,0,hmHeight,hmWidth,-hmHeight,NULL);  
  326.             GlobalFree(hGlobal);  
  327.             free(buffer);  
  328.         }  
  329.         else  
  330.             LeaveCriticalSection(&g_cs);  
  331.     }  
  332.   
  333.     //free(buffer);  
  334.     pPic->Release();  
  335.     pStm->Release();  
  336.   
  337.     return 0;  
  338. }  



你可能感兴趣的:(VC 多线程编写)