Linux C SharedMemory in Prozessen

Direkte Linux-Programmierung, POSIX
Antworten
CPipe
Beiträge: 1
Registriert: Mo Apr 11, 2016 7:20 am

Linux C SharedMemory in Prozessen

Beitrag von CPipe » Mo Apr 11, 2016 7:36 am

Guten Tag,

ich freue mich über jede Hilfe zu meiner Schwierigkeit.

Derzeit arbeite ich mich in Ubuntu 14.04 in die Linux C Programmierung ein.
Konkret geht es um Interprozess Kommunikation (IPC) und SharedMemory.
Nach erfolgreichen anlegen des SharedMemory führt jegliches Schreiben oder
Lesen zu Fault Segmentation.

Ich arbeite mit GCC v. 4.8.4

Code: Alles auswählen

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

#include <stdio.h>

#include <stdlib.h>


#define SHMMAX 2000//sizeof(int)

//0666 lesen schreiben für clienten


int main()

{

	//shm Schlüssel
	key_t key = 1234L;

	//int shm_laenge = SHMMAX;

	int shm_id = 0;
	pid_t vater_pid;

	//void *shm_ptr;
	char *shm_ptr = NULL;

	int quit = 0; //beenden der Texteingabe

	char eingabe[100];


	//erzeuge ein SHM

	//bitte IPC_EXCL nicht verwenden, falls ein SHM nicht gelöscht wurde,

	//dann kann es nicht gebunden werden. Abhalten davon tut IPC_EXCL.

	//Das Betriebssystem meldet in einem solchen Fall die SHM exitsiert schon

	// und stoppt das Erstellen.

	/*
	if( ( shm_id = shmget(key, shm_laenge, IPC_CREAT | SHM_R | SHM_W) ) < 0)
	{
		//Fehlerausgabe
		printf("\nSharedMemory nicht erstellt (%d)\n", shm_id);
		perror("SharedMemory");
		return EXIT_FAILURE;
	}
	*/

	//printf("\nDie SHMID lautet (%d)\n", shm_id);

	/*
	//Shm an den Vaterprozess binden
	if( shm_ptr = shmat(shm_id, NULL, 0) < 0)
	{
		//Fehlerausgabe
		printf("SharedMemory ist nicht angebunden\n");
		perror("shmat");
		return EXIT_FAILURE;
	}
	*/

	/*
	//pointer ausgeben
	printf("SharedMemory Pointer ist: %p\n", shm_ptr);
	*/

	//------------------------------ Prozesse erschaffen ---------------------------------------
	if( vater_pid = fork() > 0)
	{
		//ich bin der Vater
		//if( ( shm_id = shmget(key, SHMMAX, IPC_CREAT | SHM_R | SHM_W) ) < 0)
		if( ( shm_id = shmget(IPC_PRIVATE, SHMMAX, IPC_CREAT | 0777) ) < 0)
		{
			//Fehlerausgabe
			printf("\nSharedMemory nicht erstellt (%d)\n", shm_id);
			perror("SharedMemory");
			return EXIT_FAILURE;
		}

		printf("\nDie SHMID lautet (%d)\n", shm_id);
		
		//Shm an den Vaterprozess binden
		if( shm_ptr = shmat(shm_id, NULL, 0) < 0)
		{
			//Fehlerausgabe
			printf("SharedMemory ist nicht angebunden\n");
			perror("shmat");
			return EXIT_FAILURE;
		}
		
		//Texteingabe
		while(quit != 1)
		{
			printf("Geben Sie eine Nachricht ein:\n");
			fgets(eingabe, sizeof(eingabe), stdin);
			//printf("fgets erhielt: %s\n", eingabe);
			fflush(stdin);
			
			//string exit erkannt, Schleife beenden
			if(strcmp("exit", eingabe) == 0)
				quit = 1;

			//jetzt schreibe auf die shm
			sprintf(shm_ptr, "Client: %s", eingabe);
			//memcpy(shm_ptr, eingabe, sizeof(eingabe));
			
			//schiebe den Pointer weiter
			//shm_ptr += sizeof(eingabe);
			
			//Trick für Client
			//*shm_ptr = 0;
		}

		//lösche SHM
		if( shmctl(shm_id, IPC_RMID, NULL) != 0)
		{
			//Fehlerausgabe
			printf("Löschen des SHMs scheiterte!\n ");
			perror("shmctl");
		}
		else
			printf("SHM ist am Kernel gelöscht\n");
	}
	else if (vater_pid == 0)
	{
		//ich bin das Kind
	}
	else
	{
		//Fehlerausgabe
		printf("Fork ist gescheitert!\n");
		perror("fork");
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
} 

Diese Links las ich zum Thema, aber funktionieren nicht.
http://easy2code.de/shared-memory-linux-example-c/
http://stackoverflow.com/questions/5656 ... linux-in-c

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8499
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Linux C SharedMemory in Prozessen

Beitrag von Xin » Do Apr 14, 2016 9:30 pm

CPipe hat geschrieben:Derzeit arbeite ich mich in Ubuntu 14.04 in die Linux C Programmierung ein.
Konkret geht es um Interprozess Kommunikation (IPC) und SharedMemory.
Nach erfolgreichen anlegen des SharedMemory führt jegliches Schreiben oder
Lesen zu Fault Segmentation.

Ich arbeite mit GCC v. 4.8.4
Hallo cpipe,

Dein Problem ist sicherlich etwas ausgefallener, so dass sich damit nicht jeder gleich beschäftigen kann.
Wichtig dabei ist, dass das Programm sich sofort kompilieren lässt - immerhin muss sich jemand die Mühe machen das ganze nachzuvollziehen, da möchte man nicht auch noch gucken, welche Includes fehlen.

Ich selbst habe von den SharedMemory-Funktionen noch keine Ahnung, um Dir zu helfen, muss ich mir also Zeit nehmen.

Vermutlich hast Du den Fehler bereits gefunden. Wenn ja, wäre ich dankbar, wenn Du das ebenfalls schreibst, denn in dem Fall könnte ich mir die Zeit ja auch sparen. Falls nicht: Ich habe mir Dein Programm heute angesehen, es kompiliert und es abstürzen lassen.

Code: Alles auswählen

	if( ( shm_id = shmget(key, shm_laenge, IPC_CREAT | SHM_R | SHM_W) ) < 0)
...
	//Shm an den Vaterprozess binden
	if( shm_ptr = shmat(shm_id, NULL, 0) < 0)
Das sieht mir nach Copy'n'Paste aus. Was immer shmat zurück gibt ist ein Zeiger. Ich denke, dass ein Zeiger immer größer Null sein dürfte: Die Bedingung sollte also immer false sein, Das entspricht 0 und das wird shm_ptr zugewiesen.
Du musst hier Klammern setzen. Noch besser wäre, wenn erst die Zuweisung auf shm_ptr machst und dann das Ergebnis mit if abprüfst.
Ändere ich das, stürzt das Programm nicht mehr ab.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Antworten