【发布时间】:2021-12-01 11:16:49
【问题描述】:
您好,我在 Linux 中制作了小型“客户端-服务器”文件传输程序。但奇怪的事情正在发生。如果我启动第一个客户端然后服务器一切正常。 shmget() 为提供的密钥提供相同的 id。不幸的是,如果我启动第一台服务器然后启动客户端,我会在客户端中获得不同的 id,并且我无法复制数据。 我正在使用 IPC_CREAT 标志,所以它应该加入共享内存。
客户
id=shmget(138134,1,0777|IPC_CREAT);
服务器
id=shmget(138134,1,0777|IPC_CREAT);
基本信息 所以基本上有3个元素的信号量。服务器 | sem0 |共享内存 | sem1 |客户。当服务器和客户端将找到 EOF 时使用 Sem2。我一个接一个地复制数据。客户端和服务器都具有相同的功能。创建,删除等有基本的信号量和共享内存功能。唯一的区别在于main。不幸的是,代码是波兰语,但也许会有所帮助。
服务器主
utworz_nowy_semafor();//semaphore creating
upd(); //shared memory creating
upa(); //shared memory attaching
odlaczenie1=shmctl(pamiec,IPC_RMID,0); //marking shared memory to delete(waiting for detach)
FILE* we = fopen("zrodlo", "r");
if(we == NULL)
{
printf("Blad otwierania pliku wejsciowego");
exit(1);
}
else
{
printf("Otworzony plik wejsciowy\n");
}
int c;
semafor_v(0); // opening the gate
while((c = fgetc(we)) != EOF)
{
semafor_p(0); // closing the gate
wstaw(c);
semafor_v(1);
}
semafor_p(0);
wstaw(c);
semafor_v(1);
fclose(we);
printf("Zamknalem pilk zrodlowy! Czekam na sygnal od konsumenta aby zakonczyc dzialanie\$
semafor_p(2);
printf("Konsument skonczył kopiowanie. Zamykam program!\n");
odlaczenie2=shmdt(adres);
if (odlaczenie1==-1 || odlaczenie2==-1)
{
printf("Problemy z odlaczeniem pamieci dzielonej.\n");
exit(EXIT_FAILURE);
}
else printf("Pamiec dzielona zostala odlaczona.\n");
//odlacz_pamiec();
exit(EXIT_SUCCESS);
客户端主
utworz_nowy_semafor();
upd();
upa();
FILE* wy; wy = fopen("wynik", "w");
if(wy == NULL)
{
printf("Blad tworzenia pliku");
exit(1);
}
else
{
printf("Plik wynikowy utworzony!\n");
}
while(1 != 0)
{
semafor_p(1);
char c = wez();
if(c == EOF)
{
printf("Nastąpił koniec pliku. Wykonuję przerwanie petli\n");
fclose(wy);
break;
}
fputc(c, wy);
printf("Konsument odebral znak: %c\n",c);
semafor_v(0);
}
semafor_v(2);
usun_semafor();
odlaczenie1=shmctl(pamiec,IPC_RMID,0);
odlaczenie2=shmdt(adres);
if (odlaczenie1==-1 || odlaczenie2==-1)
{
printf("Problemy z odlaczeniem pamieci dzielonej.\n");
exit(EXIT_FAILURE);
}
else printf("Pamiec dzielona zostala odlaczona.\n");
exit(EXIT_SUCCESS);
【问题讨论】:
-
你能给我们更多的背景信息吗?您确定第三个显示段不是旧测试吗?
shmget的回报是什么? minimal reproducible example 呢? -
@Mathieu 第三个显示不是旧测试,现在我编辑了帖子并提供了更多详细信息
-
shmget在您的示例代码中未被调用。 -
shmget 在 upa() 函数中被调用
-
已修复:在客户端加入之前,我无法将信号量标记为分离。
标签: c linux shared-memory