我试图沟通两个程序(在一个我使用GTK和在其他我使用C编程的标准IO)。在这两个我用shmget。 shmat,...等等来传达它们。如何在GTK应用程序(或GTK和控制台应用程序)之间共享内存?
但是我不得不做很多事情来完成这些事情......两个程序都会编译,但是没有一个能够按照我的意图运行。
我真正想要做的是将数据从服务器发送到控制客户端程序的客户端(在此测试中只是在终端上打印数字),它将在从服务器接收到信号后完成其执行。
不幸的是,我不能用GTK创建它,但是我几乎在控制台应用程序中完成它,但是它在自动运行(没有用户交互性)时会在65516迭代后崩溃。在游戏程序中这可能是一个问题,但是对于某些应用程序,下面的代码可以令人满意地工作。
我的问题是:为什么在达到65516个interations(在客户端程序上调用shmat函数)后发生错误?
在我未来的应用这个错误必须避免,否则会令程序崩溃...
我怎样才能避免它,并让我的程序(客户端应用程序)运行下去?
还有其他方法通过另一个程序来控制程序?哪一个可行或更实用?
文件 SMH-02.h
#define NOT_READY -1
#define FILLED 0
#define TAKEN 1
struct Memory
{
int status;
int data[4];
int dado; // I just add this data
};
文件Console_server01.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include "shm-02.h"
#define RUN_WITH_USER // Coment this line to user interactivity
// Or uncoment it to run automactic test indefinitely until segmented fail
key_t ShmKEY;
int ShmID;
struct Memory *ShmPTR;
//---------------------------------------------------------------------
void send_data(int info)
{
while(ShmPTR->status != TAKEN);
ShmPTR->status = NOT_READY;
ShmPTR->dado = info;
ShmPTR->status = FILLED; //Server has informed client that the shared memory have been FILLED
}
//---------------------------------------------------------------------
//---------------------------------------------------------------------
int main(int argc, char *argv[])
{
int info;
ShmKEY = ftok(".", 'x');
ShmID = shmget(ShmKEY, sizeof(struct Memory), IPC_CREAT | 0666);
if (ShmID < 0)
{
printf("*** shmget error (server) ***\n");
exit(1);
}
ShmPTR = (struct Memory *) shmat(ShmID, NULL, 0);
if ((int) ShmPTR == -1)
{
printf("*** shmat error (server) ***\n");
exit(1);
}
send_data(55); // This will send some signal to the client establish connection
info = 1; //----- Value to RUN_REPEATLY ------
do
{
#ifdef RUN_WITH_USER //----------------------------------
printf("\n Type:");
printf("\n [1] To move to RIGHT");
printf("\n [2] To move to LEFT");
printf("\n [3] To move to QUIT");
printf("\n You choice is: ");
scanf("%d",&info);
#endif //----------------------------------
send_data(info);
}
while(info != 3);
shmdt((void *) ShmPTR); //Server has detached its shared memory...
shmctl(ShmID, IPC_RMID, NULL); //Server has removed its shared memory...
return 0;
}
文件Console_client01.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include "shm-02.h"
int main(void)
{
key_t ShmKEY;
int ShmID;
struct Memory *ShmPTR;
ShmKEY = ftok(".", 'x');
int i = 0;
int trigger = 0; // trigger locked
ShmID = shmget(ShmKEY, sizeof(struct Memory), 0666);
if (ShmID < 0)
{
printf("*** shmget error (client) ***\n");
exit (1); //Client exits
}
do{
ShmPTR = (struct Memory *) shmat(ShmID, NULL, 0);
if ((ShmPTR->status == FILLED)&&(trigger == 0))
{
ShmPTR->status = TAKEN;
trigger = 1; // trigger pulled
}
while (ShmPTR->status != FILLED)
{
printf("\nWaiting status = FILLED\t|\t");
switch(ShmPTR->status)
{
case -1:
printf("Current status = NOT_READY");
break;
case 0:
printf("Current status = FILLED");
break;
case 1:
printf("Current status = TAKEN");
break;
}
sleep(1); // Uncoment this line to better user interactivity
}
usleep(800); // Uncoment this line to better user interactivity
i++;
printf("\ni = %d --/// | dado = %d ", i, ShmPTR->dado);
if ((int) ShmPTR == -1)
{
printf("*** shmat error (client) ***\n");
exit(1); //Client exits
}
else
{
if (ShmPTR->dado == 55)
{
printf("\nConnection ESTABLISHED"); //Go to the LEFT
ShmPTR->status = TAKEN;
}
if (ShmPTR->dado == 3) // Exiting Program
{
ShmPTR->status = TAKEN; //Client has informed server data have been taken...
shmdt((void *) ShmPTR); //Client has detached its shared memory...
exit (0); //Client exits
}
if (ShmPTR->dado == 1)
{
printf("\n<--- move LEFT"); //Go to the LEFT
ShmPTR->status = TAKEN;
}
if (ShmPTR->dado == 2)
{
printf("\n---> move RIGHT"); // Go to the RIGHT
ShmPTR->status = TAKEN;
}
if ((ShmPTR->dado != 1)||(ShmPTR->dado != 2))
{
printf("\nIdle | dado = %d",ShmPTR->dado); //Doing NOTHING
ShmPTR->status = TAKEN;
}
}
}while (1); // 'Infinite' loop
exit(0);
}
Error after 65516 interations_Picture
你可以减少你的问题空间,它会更容易得到答案,也许开始于[先与共享内存通信](https://users.cs.cf.ac.uk/Dave.Marshall/C /node27.html),然后再尝试将它放入GTK/GUI应用程序中。 – dvhh
当你做了什么dvhh建议,请花时间也正确缩进代码。 – jku
感谢您的建议dvhh和jku。我会编辑代码和问题,我们可以在上面看到结果。 – Marcio