VC 多线程编写
来源:互联网 发布:cf网络不稳定怎么办 编辑:程序博客网 时间:2024/05/02 09:40
- #include <windows.h>
- #include <iostream.h>
- DWORD WINAPI fun1(LPVOID lpParameter);
- DWORD WINAPI fun2(LPVOID lpParameter);
- int tickets = 100;
- CRITICAL_SECTION g_cs;
- void main()
- {
- HANDLE hThread1;
- HANDLE hThread2;
- hThread1 = CreateThread(NULL,0,fun1,NULL,0,NULL);
- hThread2 = CreateThread(NULL,0,fun2,NULL,0,NULL); //第四个参数可以来传递变量从主线程进入到fun线程。
- CloseHandle(hThread1);//关掉线程句柄,不是关掉线程本身。
- CloseHandle(hThread2);
- InitializeCriticalSection(&g_cs);
- Sleep(1000);
- DeleteCriticalSection(&g_cs);
- }
- DWORD WINAPI fun1(LPVOID IpParameter)
- {
- while(TRUE)
- {
- EnterCriticalSection(&g_cs);
- if (tickets >0)
- {
- cout<<"thread1 sell ticket : "<<tickets--<<endl;
- LeaveCriticalSection(&g_cs);
- }
- else
- {
- break;
- LeaveCriticalSection(&g_cs);
- }
- }
- return 0;
- }
- DWORD WINAPI fun2(LPVOID IpParameter)
- {
- while(TRUE)
- {
- EnterCriticalSection(&g_cs);
- if (tickets >0)
- {
- cout<<"thread2 sell ticket : "<<tickets--<<endl;
- LeaveCriticalSection(&g_cs);
- }
- else
- {
- break;
- LeaveCriticalSection(&g_cs);
- }
- }
- return 0;
- }
如上程序,在主线程里面定义两个线程,分别从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*型的数组(栈)。
这也达到了数据缓存的效果。
- // Client_MuliThereadDlg.h : header file
- //
- #pragma once
- struct RECVPARAM
- {
- SOCKET sock;
- HWND hwnd;
- };
- struct a_buffer_size
- {
- char* a_buffer;
- int size;
- };
- struct ALL_BUFFER
- {
- a_buffer_size ABUFFERSIZE[100];
- int bufferPos;
- ALL_BUFFER()
- {
- bufferPos = 0;
- }
- };
- // CClient_MuliThereadDlg dialog
- class CClient_MuliThereadDlg : public CDialog
- {
- // Construction
- public:
- CClient_MuliThereadDlg(CWnd* pParent = NULL); // standard constructor
- // Dialog Data
- enum { IDD = IDD_CLIENT_MULITHEREAD_DIALOG };
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- // Implementation
- protected:
- HICON m_hIcon;
- // Generated message map functions
- virtual BOOL OnInitDialog();
- afx_msg void OnPaint();
- afx_msg HCURSOR OnQueryDragIcon();
- DECLARE_MESSAGE_MAP()
- public:
- afx_msg void OnBnClickedOk();
- public:
- BOOL InitSock(void);
- private:
- SOCKET m_socket;
- public:
- static DWORD WINAPI CClient_MuliThereadDlg::dataRecv(LPVOID IpParameter);
- public:
- static DWORD WINAPI CClient_MuliThereadDlg::dataDisp(LPVOID IpParameter);
- };
- // Client_MuliThereadDlg.cpp : implementation file
- //
- #include "stdafx.h"
- #include "Client_MuliTheread.h"
- #include "Client_MuliThereadDlg.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #endif
- // CClient_MuliThereadDlg dialog
- //int maxBuffer = 10240000;
- CRITICAL_SECTION g_cs;
- ALL_BUFFER aBuffer;
- CClient_MuliThereadDlg::CClient_MuliThereadDlg(CWnd* pParent /*=NULL*/)
- : CDialog(CClient_MuliThereadDlg::IDD, pParent)
- {
- m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
- }
- void CClient_MuliThereadDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- }
- BEGIN_MESSAGE_MAP(CClient_MuliThereadDlg, CDialog)
- ON_WM_PAINT()
- ON_WM_QUERYDRAGICON()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- // CClient_MuliThereadDlg message handlers
- BOOL CClient_MuliThereadDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- // Set the icon for this dialog. The framework does this automatically
- // when the application's main window is not a dialog
- SetIcon(m_hIcon, TRUE); // Set big icon
- SetIcon(m_hIcon, FALSE); // Set small icon
- // TODO: Add extra initialization here
- InitSock();
- RECVPARAM *pRecvParam1 = new RECVPARAM;
- RECVPARAM *pRecvParam2 = new RECVPARAM;
- pRecvParam1->sock =m_socket;
- pRecvParam1->hwnd =m_hWnd;
- pRecvParam2 = pRecvParam1;
- HANDLE mThread1 = CreateThread(NULL,0,dataRecv,(LPVOID)pRecvParam1,0,NULL);
- HANDLE mThread2 = CreateThread(NULL,0,dataDisp,(LPVOID)pRecvParam2,0,NULL);
- CloseHandle(mThread1);
- CloseHandle(mThread2);
- InitializeCriticalSection(&g_cs);
- return TRUE; // return TRUE unless you set the focus to a control
- }
- // If you add a minimize button to your dialog, you will need the code below
- // to draw the icon. For MFC applications using the document/view model,
- // this is automatically done for you by the framework.
- void CClient_MuliThereadDlg::OnPaint()
- {
- if (IsIconic())
- {
- CPaintDC dc(this); // device context for painting
- SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
- // Center icon in client rectangle
- int cxIcon = GetSystemMetrics(SM_CXICON);
- int cyIcon = GetSystemMetrics(SM_CYICON);
- CRect rect;
- GetClientRect(&rect);
- int x = (rect.Width() - cxIcon + 1) / 2;
- int y = (rect.Height() - cyIcon + 1) / 2;
- // Draw the icon
- dc.DrawIcon(x, y, m_hIcon);
- }
- else
- {
- CDialog::OnPaint();
- }
- }
- // The system calls this function to obtain the cursor to display while the user drags
- // the minimized window.
- HCURSOR CClient_MuliThereadDlg::OnQueryDragIcon()
- {
- return static_cast<HCURSOR>(m_hIcon);
- }
- void CClient_MuliThereadDlg::OnBnClickedOk()
- {
- // TODO: Add your control notification handler code here
- DeleteCriticalSection(&g_cs);
- OnOK();
- }
- BOOL CClient_MuliThereadDlg::InitSock(void)
- {
- WSADATA wsaData;
- int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
- //SOCKET m_socket;
- m_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
- sockaddr_in service;
- service.sin_family = AF_INET;
- service.sin_addr.s_addr = inet_addr("163.180.117.229");
- service.sin_port = htons( 6000 );
- if ( bind( m_socket, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR ) {
- closesocket(m_socket);
- return FALSE;
- }
- listen( m_socket, SOMAXCONN );
- return TRUE;
- }
- DWORD WINAPI CClient_MuliThereadDlg::dataRecv(LPVOID IpParameter)
- {
- SOCKET sock = ((RECVPARAM*)IpParameter)->sock;
- //HWND hwnd = ((RECVPARAM*)IpParameter)->hwnd;
- //HDC hdc = ::GetDC(hwnd);
- SOCKET AcceptSocket;
- SOCKADDR_IN serverInfo;
- int len = sizeof(SOCKADDR);
- AcceptSocket = accept(sock , (SOCKADDR*)&serverInfo, &len);
- int flag = 1;
- int PackteSize = 1024;
- int PacketCount,LastDataPacket;
- int lSzie;
- char* recvbuf;
- char* buffer_last;
- char* buffer;
- char recvbuf_count[10];
- char recvbuf_last[6];
- char temp[10];
- int pos;
- int bytesRecv,num;
- int bytesRecv_count,bytesRecv_last;
- // int test;
- int pos_temp;
- recvbuf = (char*)malloc(sizeof(char)*(PackteSize+10));
- while(1)
- {
- bytesRecv_count = recv(AcceptSocket,recvbuf_count,10,0);
- if ( bytesRecv_count == 0 )
- break;
- PacketCount = atoi(recvbuf_count);
- //receive the LastDataPacket
- bytesRecv_last = recv(AcceptSocket,recvbuf_last,6,0);
- LastDataPacket = atoi(recvbuf_last);
- lSzie = PackteSize * PacketCount + LastDataPacket;
- buffer_last = (char*)malloc(sizeof(char)*(LastDataPacket+10));
- buffer = (char*)malloc(sizeof(char)*lSzie);
- int iRecvSize;
- int iRet;
- int idx;
- int i;
- for (i=0;i<PacketCount;i++)
- {
- iRecvSize = PackteSize + 10;
- idx = 0;
- while (iRecvSize > 0)
- {
- iRet = recv(AcceptSocket, recvbuf+idx, iRecvSize, 0);
- if (iRet > 0)
- {
- idx += iRet;
- iRecvSize -= iRet;
- }
- else if (iRet == 0)
- {
- break;
- }
- else if ( iRet == SOCKET_ERROR)
- {
- break;
- }
- }
- memcpy(temp,recvbuf,10);
- pos = atoi(temp);
- memcpy(buffer+pos,recvbuf+10,PackteSize);
- }
- iRecvSize = LastDataPacket + 10;
- idx = 0;
- while (iRecvSize > 0)
- {
- iRet = recv(AcceptSocket, buffer_last+idx, iRecvSize, 0);
- if (iRet > 0)
- {
- idx += iRet;
- iRecvSize -= iRet;
- }
- else if (iRet == 0)
- {
- break;
- }
- else if ( iRet == SOCKET_ERROR)
- {
- break;
- }
- }
- memcpy(temp,buffer_last,10);
- pos = atoi(temp);
- memcpy(buffer+pos,buffer_last+10,LastDataPacket);
- EnterCriticalSection(&g_cs);
- pos_temp = aBuffer.bufferPos;
- aBuffer.ABUFFERSIZE[pos_temp].a_buffer = (char*)malloc(sizeof(char)*lSzie);
- memcpy(aBuffer.ABUFFERSIZE[pos_temp].a_buffer,buffer,lSzie);
- aBuffer.ABUFFERSIZE[pos_temp].size = lSzie;
- aBuffer.bufferPos++;
- LeaveCriticalSection(&g_cs);
- free(buffer_last);
- free(buffer);
- }
- free(recvbuf);
- closesocket(AcceptSocket);
- WSACleanup();
- return 0;
- }
- DWORD WINAPI CClient_MuliThereadDlg::dataDisp(LPVOID IpParameter)
- {
- HWND hwnd = ((RECVPARAM*)IpParameter)->hwnd;
- HDC hdc = ::GetDC(hwnd);
- IPicture* pPic;
- IStream* pStm;
- int pos_temp;
- int lSzie;
- char* buffer;
- while(TRUE)
- {
- EnterCriticalSection(&g_cs);
- if (aBuffer.bufferPos > 0)
- {
- pos_temp = aBuffer.bufferPos;
- lSzie = aBuffer.ABUFFERSIZE[pos_temp-1].size;
- buffer = (char*)malloc(sizeof(char)*lSzie);
- memcpy(buffer,aBuffer.ABUFFERSIZE[pos_temp-1].a_buffer,lSzie);
- aBuffer.bufferPos--;
- free(aBuffer.ABUFFERSIZE[pos_temp-1].a_buffer);
- LeaveCriticalSection(&g_cs);
- HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE,lSzie);
- LPVOID pvData = NULL;
- pvData = GlobalLock(hGlobal);
- memcpy(pvData,buffer,lSzie);
- GlobalUnlock(hGlobal);
- CreateStreamOnHGlobal(hGlobal,TRUE,&pStm);
- ULARGE_INTEGER pSeek;
- LARGE_INTEGER dlibMove ={0};
- pStm->Seek(dlibMove,STREAM_SEEK_SET,&pSeek);
- OleLoadPicture(pStm,lSzie,TRUE,IID_IPicture,(LPVOID*)&pPic);
- OLE_XSIZE_HIMETRIC hmWidth;
- OLE_YSIZE_HIMETRIC hmHeight;
- pPic->get_Width(&hmWidth);
- pPic->get_Height(&hmHeight);
- pPic->Render(hdc,0,0,320,240,0,hmHeight,hmWidth,-hmHeight,NULL);
- GlobalFree(hGlobal);
- free(buffer);
- }
- else
- LeaveCriticalSection(&g_cs);
- }
- //free(buffer);
- pPic->Release();
- pStm->Release();
- return 0;
- }
- VC++多线程编写示例
- VC 多线程编写
- VC++多线程编写经验
- VC 多线程编写
- vc编写多线程文件下载器
- VC:简单聊天室程序1 --- 多线程编写网络聊天室程序
- vc socket 多线程 (记录一次自己调用window 底层API编写 vc socket 多线程的服务器网络程序)
- VC多线程
- VC 多线程
- vc++多线程
- VC多线程
- vc 多线程
- VC多线程
- vc 多线程
- VC多线程
- vc多线程
- VC 多线程
- VC多线程
- 传统MVC模式
- 微软要当心了:多部游戏移植至OS X
- 二、J2ME开发环境搭建[J2ME入门开发教程]
- 40个很有用的Mac OS X Shell脚本和终端命令
- uboot 编译过程
- VC 多线程编写
- C语言关键字--- if switch do while for
- MAGE_NT_HEADERS STRUCT结构
- 蛇年谈程序员发展之路
- 2013-02-26 18:29 Gridview动态绑定mysql以及分页显示代码
- PE文件:节表(区块表)
- RelativeLayout布局 TextView覆盖其他控件解决办法
- 三、第一个J2ME程序[J2ME入门开发教程]
- PE文件详解四:PE详解之区块描述、对齐值以及RVA详解