2016-09-26 83 views
0

我试图沟通两个程序(在一个我使用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); 
} 

Running the programs_Picture

Error after 65516 interations_Picture

+1

你可以减少你的问题空间,它会更容易得到答案,也许开始于[先与共享内存通信](https://users.cs.cf.ac.uk/Dave.Marshall/C /node27.html),然后再尝试将它放入GTK/GUI应用程序中。 – dvhh

+0

当你做了什么dvhh建议,请花时间也正确缩进代码。 – jku

+0

感谢您的建议dvhh和jku。我会编辑代码和问题,我们可以在上面看到结果。 – Marcio

回答

相关问题