C中的命名管道读取奇怪的结果

Posted

技术标签:

【中文标题】C中的命名管道读取奇怪的结果【英文标题】:Named pipes in C reading weird result 【发布时间】:2015-01-17 16:31:54 【问题描述】:

我正在 Windows 上使用 C 中的命名管道实现我的第一个程序。 我正在尝试为数字 pi 实现蒙特卡洛方法。

在创建随机数时,一切都很好。然后我发送数字并在主线程上接收它。

在那里,不知何故,数据看起来很奇怪..

似乎问题出在 ConnectNamedPipe 中,因为它返回 false 此外,如果我使用句柄更改所有路径,程序会挂在 ConnectNamedPipe.. 它看起来像这样:

z:-1.#QNAN0, x:-1.#QNAN0, y:0.000000
z:1.#INF00, x:310579431956368060000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000.000000, y:0.000000
z:0.000000, x:0.000000, y:0.000000
z:0.000000, x:0.000000, y:0.000000
z:0.000000, x:0.000000, y:0.000000
z:0.000000, x:0.000000, y:0.000000
z:0.000000, x:-0.000000, y:0.000000
z:1.#INF00, x:833189623448552210000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000.000000, y:0.000000
z:0.000000, x:0.000000, y:0.000000
z:0.000000, x:0.000000, y:0.000000
z:0.000000, x:0.000000, y:0.000000
z:0.000000, x:0.000000, y:0.000000
z:0.000000, x:0.000000, y:0.000000
z:0.000000, x:0.000000, y:0.000000
z:1.#INF00, x:315573513832673330000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000.000000, y:0.000000
z:-1.#QNAN0, x:-1.#QNAN0, y:0.000000
z:1.#INF00, x:835455692328165330000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000.000000, y:0.000000
z:0.000000, x:0.000000, y:0.000000
z:0.000000, x:0.000000, y:0.000000
z:0.000000, x:0.000000, y:0.000000
z:4.000000, x:2.000000, y:0.000000
z:0.000000, x:0.000000, y:0.000000

什么时候应该是这样的:

z:4.00000 x:0.475953, y:0.983213

这是生成数字的线程的代码:

 HANDLE readpipe, writepipe;

    int a;
    BOOL   fConnected = FALSE; 
    LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe1"); 


  unsigned int __stdcall stage1(void * param) 
    srand(time(NULL));
    printf("creating...\n");
    writepipe = CreateNamedPipe(
        lpszPipename, // name of the pipe
        PIPE_ACCESS_OUTBOUND, // 1-way pipe -- send only
        PIPE_TYPE_MESSAGE, 
        PIPE_UNLIMITED_INSTANCES, 
        1024, 
        1024, 
        0, // use default wait time
        NULL // use default security attributes
    );
    printf("created...\n");
     fConnected = ConnectNamedPipe("\\\\.\\pipe\\mynamedpipe1", NULL) ? 
         TRUE : (GetLastError() == ERROR_PIPE_CONNECTED); 

         if(!fConnected)
         
            printf("Not working...");
         
    printf("connected...\n");
    double y[a];
    DWORD length;
    double x[a];
    int i;
    for (i = 0; i < a; i++) 
    
        x[i] = ((double)rand()) / (double)RAND_MAX;
        y[i] = ((double)rand()) / (double)RAND_MAX;
        printf("%f  %f\n",x[i],y[i]);

    
    printf("writing...\n");

    /*PIPE*/
    WriteFile( writepipe, x, sizeof(x), &length, 0);
    WriteFile( writepipe, y, sizeof(y), &length, 0);
    CloseHandle( writepipe );
    /*PIPE*/


    return 0;

这里是主线程:

int main( int argc, char* argv[] )
    a = atoi(argv[1]);
    srand (time(NULL));

    /*PIPE*/
    HANDLE thread1,thread2;

    /*CreatePipe( &readpipe, &writepipe, 0, 0 );*/
    /*PIPE*/

    thread1 = (HANDLE)_beginthreadex( 0, 0, &stage1, 0, 0, 0 );
    WaitForSingleObject( thread1, INFINITE );
    printf("reading.1111..\n");
    CloseHandle(thread1);
    readpipe = CreateFile( lpszPipename, GENERIC_READ,0,               NULL,           OPEN_EXISTING,  0,NULL); 
    DWORD length;
    double x[a];
    double y[a];
    printf("reading...\n");

    ReadFile( readpipe, x, sizeof(x), &length, 0);
    ReadFile( readpipe, y, sizeof(y), &length, 0 );

    double z = 0.0;
    int n=0;
    int N=0;
    int i;
    for(i=0;i<a;i++)
    
        z = x[i] * x[i] + y[i] * y[i];
        printf("z:%f, x:%f, y:%f\n",z,x[i],y[i]);
        if (z < 1) 
            n++;
        
        N++;
    

    CloseHandle( readpipe );

    printf("%d %d\n",n,N);
    double result = ((double)n / (double)N) * 4;
    printf("%f\n", result);
    getchar();

    return 0;

【问题讨论】:

请正确地提出您的问题,阅读它并尝试帮助您是双重努力。 请格式化你的代码,缩进很不均匀。读取您的数字的功能在哪里?您的实际问题是什么? 好吧,我从来没有在 Windows 上使用过命名管道,我无法弄清楚问题是什么......发送函数是 WriteFile.. 不清楚如何在生成代码中设置数组大小a。这是至关重要的,因为它控制着写作的发生方式。服务器通过atoi() 从命令行参数获取其值a。您不检查任何 I/O 操作是否成功,因此您不知道它们是否有效。 重新编写代码以消除类型错误和死锁。阅读文档可能会有所帮助。文档中有example可以参考。 【参考方案1】:

在开始线程之前在 main 函数中调用 CreateNamedPipe。应该可以的。

【讨论】:

以上是关于C中的命名管道读取奇怪的结果的主要内容,如果未能解决你的问题,请参考以下文章

c中的命名管道

两个进程之间使用的命名管道有啥问题?

C - 创建/写入/读取命名管道

从命名管道、C 程序(编写器)和 Python(读取器)获取额外数据

命名管道,如何知道在读取端读取的确切字节数。 C++, 视窗

无法从 Java 中的命名管道读取