Ich arbeite an einer Zuweisung, die IPC-Schemata verwendet, um zwischen "Server" und einem "Client" über freigegebene Dateien zu kommunizieren.Wie verbinde ich Client und Server mit dem gleichen Semaphor
Die freigegebene Datei wird in der Serveranwendung mit dem Namen Data Reader zusammen mit einem Semaphor erstellt, der initialisiert wird. Der Code dafür ist hier:
/*
*
* Function Name: initializeSemaphores()
* Description: This function initializes the semaphoreID and sets initial values for
* the semaphore.
*
* Parameters: void.
* Returns: semaphoreID (pid_t) = The semaphore ID of the semaphore we initialized.
*/
pid_t initializeSemaphore(void)
{
pid_t semaphoreID = -1;
semaphoreID = semget(IPC_PRIVATE, 1, IPC_CREAT | 0666);
if(semaphoreID == -1)
{
printf("(SERVER) Cannot create semaphore.\n");
logErrorStatus("Cannot create semaphore.", __FILE__, __LINE__);
}
printf("(SERVER) Semaphore ID is: %d\n", semaphoreID);
//Initialize semaphore to a known value
if(semctl(semaphoreID, 0, SETALL, init_values) == -1)
{
printf("(SERVER) Cannot initialize semaphores.\n");
logErrorStatus("Cannot initialize semaphores.", __FILE__, __LINE__);
semaphoreID = -1;
}
return semaphoreID;
}
/*
* Function Name: writeToSharedFile
* Description: Write machineID and status code to the shared file using semaphore control.
*
* Parameters: semaphoreID (pid_t) = The id of the semaphore we are using to communicate
* machineID (pid_t) = The id of the DataCreator to be written to the shared file.
* statusCode (int) = The status code to be written to the shared file.
* Returns: success (int) = Success code.
*/
int writeToSharedFile(pid_t semaphoreID, pid_t machineID, int statusCode)
{
int success = kNoError;
FILE* sharedFilePointer = NULL;
//Enter the critical region (gain access to the "talking stick")
if(semop (semaphoreID, &acquire_operation, 1) == -1)
{
printf("(SERVER) Cannot start critical region\n");
logErrorStatus("Cannot start critical region", __FILE__, __LINE__);
success = kCriticalRegionError;
}
//Open the shared file for appending in binary
if((sharedFilePointer = fopen(kSharedFile, "ab+")) == NULL)
{
printf("(SERVER) Cannot write to shared file.\n");
logErrorStatus("Cannot write to shared file.", __FILE__, __LINE__);
success = kSharedFileError;
}
//Write the machineID and statusCode to the shared file
fwrite(&machineID, sizeof(int), 1, sharedFilePointer);
fwrite(&statusCode, sizeof(int), 1, sharedFilePointer);
//Exit the critical region (make access to the "talking stick" available to use)
if(semop(semaphoreID, &release_operation, 1) == -1)
{
printf("(SERVER) Cannot exit critical region.\n");
logErrorStatus("Cannot exit critical region.", __FILE__, __LINE__);
success = kCriticalRegionError;
}
//Close the shared file
if(fclose(sharedFilePointer) != 0)
{
printf("(SERVER) Cannot close shared file.\n");
logErrorStatus("Cannot close shared file.", __FILE__, __LINE__);
success = kSharedFileError;
}
return success;
}
Datenmonitor („Kunde“) muss mit diesen Semaphore in Kontakt benutzen, um sicherzustellen, dass sie nie zur gleichen Zeit sprechen. Ich bin nicht sicher, ob der Client Zugriff auf die gleiche Semaphor-ID haben muss, oder welches Protokoll diese beiden Prozesse in einem Semaphor zusammen haben sollen.
Der Code für den Datenmonitor ist unten, und es ist nicht in der Lage, die kritische Region einzugeben, noch glaube ich, dass es eine korrekte Verbindung mit dem Serverprozess herstellen wird.
if(FindSharedFile())
{
while (1)
{
usleep(500000);
// attempt to set initial semaphore flag for dr
if (semop (semID, &acquire_operation, 1) == -1)
{
printf ("Cannot start critical region\n");
break;
}
if ((filePointer = fopen (kNameOfSharedFile, "rb")) != NULL)
{
if(fgets (data, sizeof (data), filePointer) != NULL)
{
printf ("DataMonitor Received data from DataReader ... <%s>\n", data);
previousMachineID = machineID;
previousStatusCode = statusCode;
// seek to end and use pointer arithmetic to calculate
// how many bytes we want to read at a time
fseek(filePointer, SEEK_END - (sizeof(int) * 2), 0);
// read data
fread(&machineID, sizeof(int), 1, filePointer);
printf("Machine id: %d\n", machineID);
fread(&statusCode, sizeof(int), 1, filePointer);
printf("Status Code: %d\n", statusCode);
// check if machine has gone off line
if(machineID == 0x00000000 || statusCode == 0xFFFFFFFF)
{
// get time stamp
time_t currentTime;
struct tm* timeinfo;
time (¤tTime);
timeinfo = localtime (¤tTime);
char* subject = "Server Has Gone Offline\n";
char* message = "";
sprintf(message, "DC Machine ID: %d \nStatus Reported: %s \nStatus Effective: %s \n", machineID, GetStatusCode(statusCode), asctime(timeinfo));
// if the email sent succesfully, break out of loop and continue to clean up environment
if(SendEmail(kNameOfSender, kNameOfRecipent, subject, message) == 0)
{
break;
}
}
if(machineID != previousMachineID && statusCode != previousStatusCode)
{
// get time stamp
time_t currentTime;
struct tm* timeinfo;
time (¤tTime);
timeinfo = localtime (¤tTime);
char* subject = "Update Status for Machine ID: ";
sprintf(subject, "Update Status for Machine ID: %d", machineID);
char* message = "";
sprintf(message, "DC Machine ID: %d \nStatus Reported: %s \nStatus Effective: %s \n", machineID, GetStatusCode(statusCode), asctime(timeinfo));
if(SendEmail(kNameOfSender, kNameOfRecipent, subject, message) == 0)
{
continue;
}
}
}
fclose (filePointer);
}
// attempt to change semaphore status
if (semop (semID, &release_operation, 1) == -1)
{
printf ("DM can't end critical region\n");
break;
}
Was ist mit den anderen Argumenten? Die Größe und die Flaggen? Irgendwas Besonderes an denen? Es scheint immer noch nicht für mich zu arbeiten –
Je nachdem, welche Art von Semaphor Semantik Sie benötigen. – rpy
In den meisten Fällen für einfache Semaphore ist ein Nsems-Wert von 1 in Ordnung, und die SemFlags werden gesetzt, um einen neuen Semaphor zu erzeugen oder zu erwarten, dass einer existiert und ggf.. Legen Sie die Berechtigungen für den Semaphor fest, um festzulegen, wer auf den Semaphor zugreifen darf (set). Sie sollten das Handbuch zu semget (und POSIX-Semaphoren) und einige Lehrbücher zu Semaphoren lesen, um ein klareres Bild davon zu bekommen, was Ihren Bedürfnissen entspricht. – rpy