实现并发的管道

Posted 芬乐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现并发的管道相关的知识,希望对你有一定的参考价值。

管道客户端

#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<Windows.h>

#define SIZE 4096
char  pipename[128] = "\\\\.\\Pipe\\cloudpipe";
HANDLE m_pipe = NULL;


int a;
int b;
void run()
{
    time_t ts;
    unsigned int num = time(&ts);
    srand(num);
    a = rand() % 1000;
    b= rand() % 1000;
}



void main()
{
    m_pipe = CreateFileA(pipename, //名称
        GENERIC_WRITE | GENERIC_READ,//读写
        0,//共享属性,1独有
        NULL,//默认安全属性
        OPEN_EXISTING,//打开已经存在的
        FILE_ATTRIBUTE_NORMAL,
        NULL);

    if (m_pipe==INVALID_HANDLE_VALUE)
    {
        printf("失败");
        return;
    }
    int nwrite;
    int nread;
    run();
    char winfo[1024] = { 0 };
    sprintf(winfo, "%d %d", a, b);//打印数据
    WriteFile(m_pipe, winfo, strlen(winfo), &nwrite, NULL);//写入
    memset(winfo, 0, sizeof(winfo));//清零
    ReadFile(m_pipe, winfo, 1024, &nread, NULL);//读取
    int  res;
    sscanf(winfo, "%d", &res);
    printf("\n%d+%d=%d", a, b, res);


    system("pause");
}

2.服务端

#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<Windows.h>

#define SIZE 4096
#define MAX_CONNECT 128
int  startthreadnum = 10;//一开始有10个线程存在
char  pipename[128] = "\\\\.\\Pipe\\cloudpipe";

typedef struct info
{
    HANDLE hthread;
    HANDLE hpipe;
    HANDLE hevent;

}PIPE_ST;

PIPE_ST  pipeinst[MAX_CONNECT];//128个结构体

DWORD WINAPI severThread(void *lp)
{
    DWORD nread = 0;
    DWORD nwrite = 0;
    DWORD dwbyte = 0;
    char szbuf[SIZE] = { 0 };
    PIPE_ST curpipe = *(PIPE_ST*)lp;//获取当前结构体
    OVERLAPPED overlap = { 0, 0, 0, 0, curpipe.hevent };//初始化一个结构体

    while (1)
    {
        memset(szbuf, 0, sizeof(szbuf));//数据清理
        ConnectNamedPipe(curpipe.hpipe, &overlap);//链接上,信息写入overlap
        WaitForSingleObject(curpipe.hevent, INFINITE);//等待
        //检测IO,如果完成就跳出
        if (!GetOverlappedResult(curpipe.hpipe,&overlap,&dwbyte,TRUE))
        {
            break;
        }
        if (!ReadFile(curpipe.hpipe,szbuf,SIZE,&nread,NULL))
        {
            puts("read fail");
            break;
        }
        int a, b;
        sscanf(szbuf, "%d %d", &a, &b);
        memset(szbuf, 0, sizeof(szbuf));//清零
        sprintf(szbuf, "%d", a + b);
        WriteFile(curpipe.hpipe, szbuf, strlen(szbuf), &nwrite, NULL);//写入

        DisconnectNamedPipe(curpipe.hpipe);//断开




    }
    return 0;


}


void start()
{
    for (int i = 0; i <startthreadnum; i++)
    {

        pipeinst[i].hpipe = CreateNamedPipeA(
            pipename,//管道名称
            PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,//管道读写属性
            PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,//消息模式,读模式,等待模式阻塞
            10,//最大个数
            0,//输出缓冲区大小
            0,//输入缓冲区大小
            1000,//超时,无限等待
            NULL);
        if (pipeinst[i].hpipe == INVALID_HANDLE_VALUE)
        {
            printf("\n%d失败",i);
            return;
        }
        //创建事件
        pipeinst[i].hevent = CreateEventA(NULL, FALSE, FALSE, FALSE);//创建事件
        //创建线程
        pipeinst[i].hthread=CreateThread(NULL,0,severThread,&pipeinst[i],0,NULL);

    }
    printf("sever start");

}
void end()
{



}
void main()
{
    start();

    system("pause");

}

 

3.压力测试

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

void main()
{


    while (1)
    {
        for (int i = 0; i < 10;i++)
        {//system()不能异步,使用shellExecuteA()
            ShellExecuteA(NULL, "open", "C:\\Users\\yincheng01\\Desktop\\code\\pipe\\Debug\\客户端.exe", NULL, NULL, 1);
            Sleep(100);
        }


        
    }



}

 

以上是关于实现并发的管道的主要内容,如果未能解决你的问题,请参考以下文章

实现并发的管道

Golang并发(Go程管道)

golang goroutine例子[golang并发代码片段]

从命名管道并发选择

Python并发编程—进程间通信

使用 FFmpeg 通过管道输出视频片段