Je reçois une erreur dans le programme suivant. Je veux montrer comment deux processus peuvent partager une variable à l'aide de sémaphore. Quelqu'un peut-il me guider?
Je ne suis pas capable de déboguer les erreurs ...
#include<stdlib.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/ipc.h>
#include<sys/sem.h>
#include<semaphore.h>
int main()
{
int pid,mutex=1;
int semid; /* semid of semaphore set */
key_t key = 1234; /* key to pass to semget() */
int nsems = 1; /* nsems to pass to semget() */
semid=semget(key,nsems,IPC_CREAT|0666);
if (semid<0)
{
perror("Semaphore creation failed ");
}
if ((pid = fork()) < 0)
{
perror("fork");
return 1;
}
else if(pid==0)
{
sem_wait(&semid);
printf("IN CHILD PROCESS :\n");
mutex++;
printf("value of shared variable =%d",mutex);
sem_post(&semid);
return 0;
}
sem_wait(&semid);
printf("IN PARENT PROCESS :\n");
mutex--;
printf("value of shared variable =%d",mutex);
sem_post(&semid);
return 0;
}
Vos principes fondamentaux sont incorrects, le programme ne fonctionnera pas, alors parcourez les bases et réécrivez le programme.
Certaines des corrections que vous devez faire sont les suivantes:
1) Vous devez créer une variable de type sémaphore
sem_t semvar;
2) Les fonctions sem_wait()
, sem_post()
nécessitent la variable sémaphore, mais vous transmettez l'id du sémaphore, ce qui n'a aucun sens.
sem_wait(&semvar);
//your critical section code
sem_post(&semvar);
3) Vous passez le sémaphore à sem_wait()
et sem_post()
sans l'initialiser. Vous devez l'initialiser à 1 (dans votre cas) avant de l'utiliser, sinon vous aurez une impasse.
ret = semctl( semid, 1, SETVAL, sem);
if (ret == 1)
perror("Semaphore failed to initialize");
Étudiez les API de sémaphore à partir de la page de manuel et suivez cet exemple exemple .
Le problème fondamental de votre code est que vous mélangez deux API. Malheureusement, les ressources en ligne ne sont pas très douées pour le signaler, mais il existe deux API de sémaphore sur les systèmes de type UNIX:
En regardant le code ci-dessus, vous avez utilisé semget () à partir de l'API System V et tenté de poster via sem_post (), qui provient de l'API POSIX. Il n'est pas possible de les mélanger.
Pour choisir l’API de sémaphore que vous voulez, vous n’avez pas autant de ressources de qualité. Le meilleur simple est la "Programmation réseau Unix" de Stevens. La section qui vous intéresse probablement est dans le Vol # 2.
Ces deux API sont étonnamment différentes. Les deux prennent en charge les sémaphores de style manuel, mais il convient de mentionner quelques points positifs et négatifs dans l'API System V:
Variez le taux de consommation et le taux de production (en utilisant le sommeil), afin de mieux comprendre le fonctionnement du code. Le code ci-dessous est la simulation consommateur-producteur (dépassant la limite maximale du conteneur).
Code pour votre référence:
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
sem_t semP, semC;
int stock_count = 0;
const int stock_max_limit=5;
void *producer(void *arg) {
int i, sum=0;
for (i = 0; i < 10; i++) {
while(stock_max_limit == stock_count){
printf("stock overflow, production on wait..\n");
sem_wait(&semC);
printf("production operation continues..\n");
}
sleep(1); //production decided here
stock_count++;
printf("P::stock-count : %d\n",stock_count);
sem_post(&semP);
printf("P::post signal..\n");
}
}
void *consumer(void *arg) {
int i, sum=0;
for (i = 0; i < 10; i++) {
while(0 == stock_count){
printf("stock empty, consumer on wait..\n");
sem_wait(&semP);
printf("consumer operation continues..\n");
}
sleep(2); //consumer rate decided here
stock_count--;
printf("C::stock-count : %d\n", stock_count);
sem_post(&semC);
printf("C::post signal..\n");
}
}
int main(void) {
pthread_t tid0,tid1;
sem_init(&semP, 0, 0);
sem_init(&semC, 0, 0);
pthread_create(&tid0, NULL, consumer, NULL);
pthread_create(&tid1, NULL, producer, NULL);
pthread_join(tid0, NULL);
pthread_join(tid1, NULL);
sem_destroy(&semC);
sem_destroy(&semP);
return 0;
}
Veuillez vérifier cet exemple de code ci-dessous pour la mise en œuvre du sémaphore (verrouiller et déverrouiller).
#include<stdio.h>
#include<stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include<string.h>
#include<malloc.h>
#include <sys/sem.h>
int main()
{
int key,share_id,num;
char *data;
int semid;
struct sembuf sb={0,-1,0};
key=ftok(".",'a');
if(key == -1 ) {
printf("\n\n Initialization Falied of shared memory \n\n");
return 1;
}
share_id=shmget(key,1024,IPC_CREAT|0744);
if(share_id == -1 ) {
printf("\n\n Error captured while share memory allocation\n\n");
return 1;
}
data=(char *)shmat(share_id,(void *)0,0);
strcpy(data,"Testing string\n");
if(!fork()) { //Child Porcess
sb.sem_op=-1; //Lock
semop(share_id,(struct sembuf *)&sb,1);
strncat(data,"feeding form child\n",20);
sb.sem_op=1;//Unlock
semop(share_id,(struct sembuf *)&sb,1);
_Exit(0);
} else { //Parent Process
sb.sem_op=-1; //Lock
semop(share_id,(struct sembuf *)&sb,1);
strncat(data,"feeding form parent\n",20);
sb.sem_op=1;//Unlock
semop(share_id,(struct sembuf *)&sb,1);
}
return 0;
}