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

标签 c windows pipe named-pipes

我正在 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;
}

最佳答案

在开始线程之前,在主函数中调用 CreateNamedPipe。这应该可行。

关于c - C 中的命名管道读取奇怪的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28001642/

相关文章:

windows - Git 配置别名不再起作用

c - 当通过管道提供 STDIN 时,getchar() 在 EOF 上循环

c - 如何从 32 位数字中提取位

c - 具有参数的宏与具有相同名称的变量的宏扩展

c - 在 C 中使用套接字服务器的 HTML 头请求

php - NET::ERR_CERT_DATE_INVALID 本地开发 (xampp)

c - 在C中使用数学库显示1弧度的正弦四舍五入到小数点后三位

c# - 从浏览器控件获取 <DIV> 标签

python - 本地机与多个独立进程的进程间通信(1个服务器,n个客户端)

javascript - 通过管道同时允许多个过滤器值 - Angular