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 <pthread.h>
#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++ 如何在构造函数中启动一个线程,从命名管道读取数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何从erlang读/写到命名管道?

在断开连接之前等待读取命名管道

Java中命名管道的并发读/写(在Windows上)

Linux。 Python。从命名管道读取

如何在 Mac OS 上用 C++ 实现命名管道?

如何在 dll 项目中的 C++ 中创建命名空间和构造函数?