簡體   English   中英

使用兩個單向管道的雙向通訊

[英]two way communication using two unidirectional pipes

嗨,您已經編寫了一個代碼,以便父級通過管道發送消息,孩子接收該消息並將其打印到屏幕上……然后孩子應回復一個,而父級則在管道內打印味精..該代碼運行良好與父級到子級之間的通信..但是,當涉及到相反的close()時,返回錯誤並且消息未傳遞。請注意,我還使用共享內存來進行一些同步和控制。孩子和父母之間的特殊類型的管道..但是如果要達到這個目的,我想使用一般情況下的一種,請告訴我是否正確..這是代碼

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/wait.h>
#include <sys/shm.h>
#include <errno.h>
#include <sched.h>
#include <string.h>
int main()
{
////creating shared memory with check///
int  shmid ;
int err;
char *shm;
shmid = shmget(IPC_PRIVATE,3 ,IPC_CREAT | IPC_EXCL | 0666 );
shm=shmat(shmid,0, IPC_CREAT | IPC_EXCL | 0666  );
if (shmid > -1)
{
printf("shared memory created succefully\n");
shm[0]='C';
shm[1]='C';
shm[2]='C';
}
else
{
return 0;
}


/////////////////////////////////////////

//////////making pipe with check/////////
int  testpipe[2];
int  size_ptr ;
char buff1[51];
char buff2[51];
char buff3[51];
char buff4[51];
int check;
check = pipe(testpipe);
if (check > -1)
{
printf("pipe created succefully\n");
}
else
{
return 0 ;
}
////////////////////////////////////////


///////////making new process///////////
pid_t pid ;
pid = fork();
////////////////////////////////////////


///////////Executing process ///////////
    if (pid > 0) //am in parent
    {


//////////partA////////////////////
     strcpy(buff1,"Hi am tweeting now ..\n");
    // err = close(testpipe[0]);
     printf("... Close state %d \n",err);
     write(testpipe[1],buff1,25);
     close(testpipe[1]);
     printf("partA Ended ... Close state %d \n");

/////////////////////////////////////
shm[0] = 'O'; // lock 2 is opened here

shm[1] = 'C'; // lock 1 is closed
while(shm[1] != 'O');
/////////////////////////////////////

//////////partD///////////////////
    //close(testpipe[1]);
    err = read(testpipe[0],buff4,25);
    //close(testpipe[1]);
    printf(" error state%i \n",err);
    printf("the output is : %s\n",buff4);
    printf("part D Ended ...\n");
    printf("Close state %d ... %i \n",err,EACCES);
    shmdt(shm);
    return 0;

    }
    else if (pid ==0) // am in child now
    {
    while(shm[0]!= 'O');  //from child read'

    ///////////////////////////////////

    //////////partb////////////////////
    read(testpipe[0],buff2,25);
    //err = close(testpipe[0]);
    printf("Close state %d \n",err);
    printf("the output is : %s\n",buff2);
    printf("partB Ended ... Close state %d\n",err);
    //close(testpipe[0]);
    //////////////////////////////////

    ///////////////    /part c////////////
     close(testpipe[0]);
     err = write(testpipe[1],buff3,25);
     printf("III... Close state %d \n",err);
     err = close(testpipe[1]);
     printf("Close state %d \n",err);
     printf("partC Ended ..\n");
     shm[1] ='O';
/////////////////////////////////////////////////
     //shm[1] = 'O';
     shm[0] = 'C';
     while(shm[0]!= 'O');
     printf("process child closed\n");

    }
    else{
     printf("Error Ocuured");
    }
//////////////////////////////////////////



}

編輯:我在這里更改了終端輸出的屏幕截圖的標題

嗨,您已經編寫了一個代碼,以便父級通過管道發送消息,孩子接收該消息並將其打印到屏幕上……然后孩子應回復一個,而父級則在管道內打印味精..該代碼運行良好與父母到孩子的溝通..但是當涉及到相反的close()時,返回錯誤並且消息沒有通過...

您的代碼顯示有關close()的消息,但是就您目前的代碼而言,這些消息大部分不會報告close()調用的實際返回值。 您會遇到各種各樣的錯誤。

但是,您如何知道消息未傳遞? 您從從未初始化或寫入的buff3寫入管道。 那么,您如何識別消息是否已通過? 如果幸運的話,您將傳遞第一個字節為'\\0'的消息,以便在您打印時將其用作空字符串。

請注意,我還使用共享內存進行一些同步和控制。

不,你沒有。 一個人可以使用共享內存來承載同步對象,例如進程共享的信號量和互斥體,但是共享內存本身並不提供任何同步語義。 因此,您的程序包含數據競爭,因此其行為是不確定的。

對於您似乎正在執行的那種鎖定,我將建議使用信號量,但首先並不需要它。 適當的管道使用不需要額外的同步。

在這種情況下,“適當的”是對每個通訊方向使用不同的管道。 盡管可以在兩個方向上僅使用一個,但這樣做很麻煩且不必要。

我知道孩子和父母之間有一種特殊的管道

父進程和子進程之間沒有特殊類型的管道。

進程通常可以通過自身調用pipe()或從其父進程繼承一個或多個打開的管道端文件描述符來訪問通過pipe()函數創建的pipe() 當以這種方式獲得訪問權限時,只有具有共同祖先的進程才能通過管道相互通信。 盡管父進程和子進程之間的通信是一個常見的示例,但此類管道絕不限於該特定使用模式。


總體:

  • 我的主要建議是放棄共享內存和不起作用的“鎖”,而是使用兩個管道,每個方向一個。

  • 如果必須僅使用一個管道,則執行適當的同步。 出於您的明顯目的,使用一個或兩個信號量(進程共享和駐留在共享內存中)似乎足以控制在任何給定時間允許從管道讀取哪個進程。 也有其他選擇,但是僅共享內存無法滿足您的需求。

並使用共享內存同步過程操作(r / w)..它起作用了..

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/wait.h>
#include <sys/shm.h>
#include <errno.h>
#include <sched.h>
#include <string.h>

#define parent_read parent_child[0]
#define parent_write parent_child[1]
#define child_read child_parent[0]
#define child_write child_parent[1]

int main()
{
////creating shared memory with check///
int  shmid ;
int err;
char *shm;
shmid = shmget(IPC_PRIVATE,4 ,IPC_CREAT | IPC_EXCL | 0666 );
shm=shmat(shmid,0, IPC_CREAT | IPC_EXCL | 0666  );
if (shmid > -1)
{
printf("shared memory created succefully\n");
shm[0]='I';
shm[1]='I';

}
else
{
return 0;
}


/////////////////////////////////////////

//////////making pipe with check/////////
int  parent_child[2];
int  child_parent[2];
int  size_ptr ;
char buff1[51];
char buff2[51];
char buff3[51];
char buff4[51];
int check1;
int check2;
check1 = pipe(parent_child);
check2 = pipe(child_parent);
if (check1 > -1 && check2 > -1)
{
printf("pipe 1 created succefully\n");
}
else
{
return 0 ;
}
////////////////////////////////////////


///////////making new process///////////
pid_t pid ;
pid = fork();
////////////////////////////////////////


///////////Executing process ///////////






    if (pid > 0) //am in parent
    {


//////////partA////////////////////
     strcpy(buff1,"Hi am tweeting now ..\n");
     close(parent_read);
     printf("... Close state %d \n",err);
     write(parent_write,buff1,25);
     close(parent_write);
     printf("partA Ended ... Close state %d \n");


/////////////////////////////////////
    shm[1] = 'B';
    shm[0]='A';
    while(shm[0] == 'A');
//////////partD///////////////////



    close(child_write);
    printf(" error state%i \n",err);
    read(child_read,buff4,25);
    close(child_read);
    printf("from child  : %s\n",buff4);
    printf("part D Ended ...\n");
    shmdt(shm);
    return 0;

    }








    else if (pid ==0) // am in child now
    {

    while(shm[1] == 'I');
    //////////partb////////////////////
    close(parent_write);
    read(parent_read,buff2,25);
    close(parent_read);
    printf("Close state %d \n",err);
    printf("from parent : %s\n",buff2);
    printf("partB Ended ... Close state %d\n",err);
    //close(testpipe[0]);
    //////////////////////////////////

    ///////////////    /part c////////////
     close(child_read);
     strcpy(buff3,"Hello from the other side...");
     err = write(child_write,buff3,25);
     printf("III... Close state %d \n",err);
     err = close(child_write);
     printf("Close state %d \n",err);
     printf("partC Ended ..\n");
     printf("process child closed\n");
     shm[0]='D';
    }
    else{
     printf("Error Ocuured");
    }
//////////////////////////////////////////



}

父母對孩子:tweety評論父母對孩子:你好,另一邊

屏幕截圖: 終端上的輸出

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM