次のプログラムでエラーが発生します。セマフォを使用して2つのプロセスが変数を共有する方法を示したいと思います。誰でも私を案内できますか?
エラーをデバッグできません...
#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;
}
あなたの基礎は間違っている、プログラムは動作しませんので、基本を通過してプログラムを書き直してください。
修正する必要があるのは次のとおりです。
1)セマフォ型の変数を作成する必要があります
_sem_t semvar;
_
2)関数sem_wait()
、sem_post()
はセマフォ変数を必要としますが、セマフォIDを渡しているため、意味がありません。
_sem_wait(&semvar);
//your critical section code
sem_post(&semvar);
_
3)セマフォを初期化せずにsem_wait()
およびsem_post()
に渡します。使用する前に1に初期化する必要があります(そうでない場合)。そうしないと、デッドロックが発生します。
_ret = semctl( semid, 1, SETVAL, sem);
if (ret == 1)
perror("Semaphore failed to initialize");
_
マニュアルページからセマフォAPIを調べて、これを確認してください 例 。
コードの基本的な問題は、2つのAPIを混在させることです。残念ながら、オンラインリソースはこれを指摘するのに優れていませんが、UNIXのようなシステムには2つのセマフォAPIがあります。
上記のコードを見て、System V APIのsemget()を使用し、POSIX APIのsem_post()を使用して投稿しようとしました。それらを混合することはできません。
必要なセマフォAPIを決定するには、それほど多くの優れたリソースはありません。最も簡単なのは、Stevensによる「Unix Network Programming」です。おそらく興味のあるセクションは第2巻です。
これら2つのAPIは驚くほど異なります。どちらも教科書スタイルのセマフォをサポートしていますが、言及する価値のあるSystem V APIにはいくつかの長所と短所があります。
コードの操作をよりよく理解するために、消費者レートと生産者レート(スリープを使用)を変更します。以下のコードは、消費者と生産者のシミュレーションです(コンテナの上限を超えています)。
参照用のコード:
#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;
}
セマフォの実装(ロックおよびロック解除)のサンプルコードを以下で確認してください。
#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;
}