C++:进程间通讯(部分转载,个人整理)
来源:互联网 发布:如何入驻天猫淘宝商城 编辑:程序博客网 时间:2024/06/10 01:45
/** * 主题:多线程和多进程技术 * */Q1: C++进程间通讯的方式 管道(命名管道,匿名管道),socket,事件event,共享内存,消息队列实例:命名管道实例/** * 方案如下所示 * 管道服务端:CreateNamedPipe(创建管道HANDLE hPipe) -> ConnectNamedPipe(连接客户端)-> (WriteFile)往管道写数据/(readFile)往管道读数据 * 管道客户端: WaitNamedPipe(等待命名管道实例有效,设置超时时间) -> CreateFile(打开管道,返回命名管道句柄) -> (WriteFile)往管道写数据/(readFile)往管道读数据 * 小结:api函数:CreateNamePipe,ConnectNamedPipe,WaitNamedPipe.CreateFile,WriteFile,ReadFile */#include "stdafx.h" #include <stdio.h> #include <windows.h> #include <ctime> int main(int argc,_TCHAR *argv[]){ srand(time(NULL)); char buf[256] = ""; DWORD rlen = 0; HANDLE hPipe = CreateNamedPipe( TEXT("\\\\.\\Pipe\\mypipe"), //管道名 PIPE_ACCESS_DUPLEX, //管道类型 PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE|PIPE_WAIT, //管道参数 PIPE_UNLIMITED_INSTANCES, //管道能创建的最大实例数量 0, //输出缓冲区长度 0表示默认 0, //输入缓冲区长度 0表示默认 NMPWAIT_WAIT_FOREVER, //超时时间 NULL); if(INVALID_HANDLE_VALUE == hPipe) { printf("Create Pipe Error(%d)\n",GetLastError()); } // 创建命名管道成功 else { //阻塞等待客户端连接 printf("Waiting For Client Connection...\n"); if(ConnectNamedPipe(hPipe,NULL) == null) { printf("Connection failed!\n"); } else { printf("Connection Success!\n"); } // 进程间数据通讯 while(true) { // 接收客户端发送过来的内容 if(ReadFile(hPipe,buf,256,&rlen,NULL) == FALSE) { printf("Read Data From Pipe Failed!\n"); break; } // 向客户端发送内容 else { printf("From Client: data = %s, size = %d\n", buf, rlen); char wbuf[256] = ""; sprintf(wbuf, "%s%d", wbuf, rand()%1000); DWORD wlen = 0; WriteFile(hPipe,wbuf,sizeof(buf),&wlen,0); printf("To Client: data = %s, size = %d\n", wbuf, wlen); Sleep(1000); } } CloseHandle(hPipe); // 关闭管道 } system("PAUSE");}// 命名管道客户端#include "stdafx.h" 02.#include <stdio.h> 03.#include <windows.h> 04.#include <ctime> 05. 06.int main(int argc, _TCHAR* argv[]) 07.{ 08. srand(time(NULL)); 09. 10. DWORD wlen = 0; 11. Sleep(1000);//等待pipe的创建成功! 12. 13. BOOL bRet = WaitNamedPipe(TEXT("\\\\.\\Pipe\\mypipe"), NMPWAIT_WAIT_FOREVER); 14. 15. if (!bRet) 16. { 17. printf("connect the namedPipe failed!\n"); 18. return 0; 19. } 20. 21. HANDLE hPipe=CreateFile( //管道属于一种特殊的文件 22. TEXT("\\\\.\\Pipe\\mypipe"), //创建的文件名 23. GENERIC_READ | GENERIC_WRITE, //文件模式 24. 0, //是否共享 25. NULL, //指向一个SECURITY_ATTRIBUTES结构的指针 26. OPEN_EXISTING, //创建参数 27. FILE_ATTRIBUTE_NORMAL, //文件属性(隐藏,只读)NORMAL为默认属性 28. NULL); //模板创建文件的句柄 29. 30. if (INVALID_HANDLE_VALUE == hPipe) 31. { 32. printf("open the exit pipe failed!\n"); 33. } 34. else 35. { 36. while(true) 37. { 38. char buf[256] = ""; 39. sprintf(buf,"%s%d",buf,rand()%1000); 40. if(WriteFile(hPipe,buf,sizeof(buf),&wlen,0)==FALSE) //向服务器发送内容 41. { 42. printf("write to pipe failed!\n"); 43. break; 44. } 45. else 46. { 47. printf("To Server: data = %s, size = %d\n", buf, wlen); 48. char rbuf[256] = ""; 49. DWORD rlen = 0; 50. ReadFile(hPipe, rbuf, sizeof(rbuf), &rlen, 0); //接受服务发送过来的内容 51. printf("From Server: data = %s, size = %d\n", rbuf, rlen); 52. } 53. Sleep(1000); 54. } 55. CloseHandle(hPipe);//关闭管道 56. } 57. 58. system("PAUSE"); 59. return 0; 60.} 实例:socket(此处代码重点在互斥体,实现对共享资源的访问保护)ex:socket的客户端,多线程实例,访问共享资源#include <iostream>#include <Winsock2.h>#include <list>#include <string>#include <cstdio>#paramea comment(lib,"Ws2_32.lib")using namespace std;/** * @:全局变量,供多个子线程访问 */list<string> str_a;list<string> str_b;list<string> str_c;/** * @:加锁访问共享资源(互斥锁) */HANDLE Lock(LPCWSTR name){ HANDLE mutex; // 首先访问互斥锁,获取互斥体对象句柄(openmutex)。若失败则创建互斥对象,否则等待获取此互斥对象的控制权(WaitForSingleObject) mutext = openmutex(MUTEXT_ALL_ACCESS,FALSE,name); if(NULL == mutext) { mutex = CreateMutex(NULL,TURE,name); } else { /** * WaitForSingleObject函数用来检测hHandle事件的信号状态,在某一线程中调用该函数时,线程暂时挂起,如果在挂起的dwMilliseconds毫秒内,线程所等待的对象变为有信号状态,则该函数立即返回; */ WaitForSingleObject(hMutex,INFINITE); } return mutex;}/** * @:释放互斥锁,供其他线程可访问共享资源 */ bool Unlock(HANDLE mutex) { // 释放互斥体对象的控制权 if(0 == ReleaseMutex(mutex)) { return false; } else { CLoseHandle(mutex); mutex = NULL; return true; }}// socket client threadDWORD WINAPI ClientThread(LPVOID lpParameter){ SOCKET ClientSocket = (SOCKET)lpParameter; char recvBuf[1000]; while(true) { memset(recvBuf,0x00,sizeof(recvBuf)); recv(ClientSocket,recvBuf,sizeof(recvBuf),0); HANDL mutex_a,mute_b,mutex_c; mutex_a = Lock( L"mutex"); str_a.push_back(string(recvBuf)); UnLock(mutex_a); mutex_b= Lock(L"mutex"); str_b.push_back(streing(recvBuf)); Unlock(mutex_b); mutex_c = Lock(L"mutex"); str_c.push_back(string(recvBuf)); Unlock(mutex_c); } return 0;}DWORD WINAPI AProcess(LPVOID lpParametr){ while(true) { HANDLE mutex = Lock(L"mutex"); if(!str_a.empty()) { string str = str_a.front(); str_a.pop_front(); printf("A: %s\n", str.c_str()); } Unlock(mutex); }}DWORD WINAPI BProccess(LPVOID lpParameter){ while(true) { HANDLE mutex = Lock(L"mutex"); if (!str_b.empty()) { string str = str_b.front(); str_b.pop_front(); printf("B: %s\n", str.c_str()); } Unlock(mutex); }}DWORD WINAPI CProccess(LPVOID lpParameter){ while(true) { HANDLE mutex = Lock(L"mutex"); if (!str_c.empty()) { string str = str_c.front(); str_c.pop_front(); printf("C: %s\n", str.c_str()); } Unlock(mutex); }}int main(){// 加载socket动态链接库(dll) WORD wVersionRequested; WSADATA wsaData; // 这结构是用于接收Wjndows Socket的结构信息的 int err; wVersionRequested = MAKEWORD( 1, 1 ); // 请求1.1版本的WinSock库 err = WSAStartup( wVersionRequested, &wsaData ); if ( err != 0 ) { return -1; // 返回值为零的时候是表示成功申请WSAStartup } if ( LOBYTE( wsaData.wVersion ) != 1 || HIBYTE( wsaData.wVersion ) != 1 ) { // 检查这个低字节是不是1,高字节是不是1以确定是否我们所请求的1.1版本 // 否则的话,调用WSACleanup()清除信息,结束函数 WSACleanup( ); return -1; }// 创建socket操作,建立流式套接字,返回套接字号sockClient // SOCKET socket(int af, int type, int protocol); // 第一个参数,指定地址簇(TCP/IP只能是AF_INET,也可写成PF_INET) // 第二个,选择套接字的类型(流式套接字),第三个,特定地址家族相关协议(0为自动) SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);// 将套接字sockClient与远程主机相连 // int connect( SOCKET s, const struct sockaddr* name, int namelen); // 第一个参数:需要进行连接操作的套接字 // 第二个参数:设定所需要连接的地址信息 // 第三个参数:地址的长度 SOCKADDR_IN addrSrv; addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); // 本地回路地址是127.0.0.1; addrSrv.sin_family = AF_INET; addrSrv.sin_port = htons(8000); connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR)); HANDLE hThread = CreateThread(NULL, 0, ClientThread, (LPVOID)sockClient, 0, NULL); HANDLE hThread_a = CreateThread(NULL, 0, AProccess, (LPVOID)NULL, 0, NULL); HANDLE hThread_b = CreateThread(NULL, 0, BProccess, (LPVOID)NULL, 0, NULL); HANDLE hThread_c = CreateThread(NULL, 0, CProccess, (LPVOID)NULL, 0, NULL); while(true); printf("End linking...\n"); closesocket(sockClient); WSACleanup(); // 终止对套接字库的使用 printf("\n"); system("pause"); return 0;}
0 0
- C++:进程间通讯(部分转载,个人整理)
- C++:共享内存(进程间通讯)(转载)
- 转载:进程间通讯机制
- 【转载】C#进程间通讯
- UNIX进程间通讯(IPC)简介(小寿转载!)
- linux 进程间通讯方法整理
- C#进程间通讯技术-整理。
- linux进程间通讯(IPC)学习整理
- 个人学习笔记(部分转载)
- delphi 进程间通讯(管道通讯)
- Linux C之进程间通讯
- 进程与线程(转载+整理)
- C#部分知识个人整理
- 关于C中的部分小知识点(都是转载,个人学习,如有侵权,请联系我删除~谢谢!)
- java试题整理1(附部分个人理解)
- C笔试部分整理
- DDE进程通讯C/C++
- jsp中文乱码问题整理(部分转载他人)
- Java温习——面向对象第三部分
- VPN篇(5.4) 01. SSL VPN
- JAVA日期类求年龄并求出大于指定年龄的学生。本人菜鸟,第一次发JAVA博客,也是第一次发博客!望大家交流指正!
- Lambda&Java多核编程-5-函数式接口与function包
- 【Mybatis】 JdbcType 与 JavaType对应关系
- C++:进程间通讯(部分转载,个人整理)
- Java基于JavaMail实现向QQ邮箱发送邮件
- Jekyll搭建lanmps.com站点
- HWSoft命令使用说明(二)---管线绘制
- JSON对null的处理
- 网站注册登录注销功能实现
- 内联元素和块级元素
- 我的选择
- 初探Android内存泄漏