我試圖溝通兩個程序(在一個我使用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