2016-09-26 82 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

回答

相關問題