[英]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.