c++ 如何在构造函数中启动一个线程,从命名管道读取数据?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c++ 如何在构造函数中启动一个线程,从命名管道读取数据?相关的知识,希望对你有一定的参考价值。
想用构造函数CFetionPipe()启动线程ReadThread,它循环调用CFetionPipe类的函数ReadString(),对收到的管道消息进行处理和响应。CFetionPipe类在千里眼的回答贴出来了。线程ReadThread函数要实例化CFetionPipe类,才能使用 ReadString()函数,而实例化CFetionPipe类,构造函数又要启动线程ReadThread,现在无法实现。求更正代码或更巧妙的处理。
DWORD WINAPI CUtils::ReadThread(LPVOID pParam)
char* readStr;
char c;
while(true)
//readStr = ReadString();
readStr = "Login";
if(readStr == "Login")
c = '1';
if(readStr == "Msg")
c = '2';
switch(c)
case '1':
...//Pipe消息处理代码
break;
return 0;
1、C++多线程也可以使用UNIX C的库函数,pthread_mutex_t,pthread_create,pthread_cond_t,pthread_detach,pthread_mutex_lock/unlock,等等。在使用多线程的时候,你需要先创建线程,使用pthread_create,你可以使主线程等待子线程使用pthread_join,也可以使线程分离,使用pthread_detach。线程使用中最大的问题就是同步问题,一般使用生产着消费者模型进行处理,使用条件变量pthread_cond_t,pthread_mutex,pthread_cond_wait来实现。
2、例程(创建5个线程):
#include <stdlib.h>
void* work_thread(void* arg)
//线程执行体
return 0;
int main(int argc,char* argv[])
int nthread = 5;//创建线程的个数
pthread_t tid;//声明一个线程ID的变量;
for(int i=0;i<nthread;i++)
pthread_create(&tid,NULL,work_thread,NULL);
sleep(60);//睡眠一分钟,可以看下线程的运行情况,不然主进程会很快节结束了。
pthread_create(&tid,NULL,work_thread,NULL);//创建线程的函数,第一个参数返回线程的ID;第二个参数是线程的属性,一般都置为NULL;第三个参数是线程函数,线程在启动以后,会自动执行这个函数;第四个参数是线程函数的参数,如果有需要传递给线程函数的参数,可以放在这个位置,可以是基础类型,如果你有不止一个参数想传进线程函数,可以做一个结构体,然后传入。 参考技术A #include "stdafx.h"
#include "FetionPipe.h"
#include <windows.h>
#include <afxwin.h>
#include "Utils.h"
CFetionPipe::CFetionPipe()
CUtils::hThread = CreateThread(NULL,0,CUtils::ReadThread,(LPVOID)NULL,0,&CUtils::dwThread);
CloseHandle(CUtils::hThread);
CFetionPipe::~CFetionPipe()
void CFetionPipe::ClientCreateFile()
FullPipeName="\\\\\\\\.\\\\pipe\\\\FetionPipe";
BOOL ret = WaitNamedPipe(FullPipeName,5000);
if(!ret)
//ClientMsg = "管道忙或者没有启动...\\n";
return;
m_hPipe = CreateFile(FullPipeName,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(m_hPipe == INVALID_HANDLE_VALUE)
char szErr[256] = "";
DWORD dwErr = GetLastError();
sprintf(szErr,"%l",dwErr);
//ClientMsg = szErr;
return;
//ClentMsg = "管道打开了";
void CFetionPipe::WirteString(char* szMsg)
DWORD dwSize = strlen(szMsg) + 1;
DWORD dwBytesWritten = 0;
BOOL ret = WriteFile(m_hPipe,&dwSize,4,&dwBytesWritten,NULL);
if(ret)
BOOL ret2 = WriteFile(m_hPipe,szMsg,dwSize,&dwBytesWritten,NULL);
char* CFetionPipe::ReadString()
char* readStr;
DWORD drSize = 0;
DWORD dwBytesRead = 0;
BOOL ret = ReadFile(m_hPipe, &drSize, 4, &dwBytesRead, NULL);
if(ret)
readStr = new char[drSize];
BOOL ret2 = ReadFile(m_hPipe, readStr, drSize, &dwBytesRead, NULL);
return readStr;
本回答被提问者采纳
如何在 Mac OS 上用 C++ 实现命名管道?
【中文标题】如何在 Mac OS 上用 C++ 实现命名管道?【英文标题】:How to implement a named Pipe in C++ on Mac OS? 【发布时间】:2017-04-23 21:59:10 【问题描述】:我正在开发一个我想与 Java 程序(JAR 文件)通信的 c++ 程序。
C++ 将写入管道,而 Java 端将从管道中读出。我已经在 Windows 中实现了这个功能。请不要推荐我如何在这两个程序之间进行通信的替代方式;我已经探索和测试了很多。
【问题讨论】:
欢迎来到 Stack Overflow!请take the tour 了解该网站的运作方式以及此处的主题问题,并相应地编辑您的问题。另见:Why is "Can someone help me?" not an actual question? man 2 mkfifo 你的问题解决了吗? 【参考方案1】:一个简单的方法是从 c++ 程序写入 std::out
并在 java 程序中从 std::in
读取。您使用mkfifo
创建管道,然后启动您的 cpp 程序并将其输出重定向到管道,然后启动您的 java 程序并将其输入重定向到管道。
调用看起来像这样
mkfifo myPipe
./cppProgramm > myPipe&
java javaProgramm < myPipe&
【讨论】:
以上是关于c++ 如何在构造函数中启动一个线程,从命名管道读取数据?的主要内容,如果未能解决你的问题,请参考以下文章