我在linux中編寫了一個簡單的項目用於共享內存。兩個程序共享內存,一個是給它寫信,另一個是從它讀取它們。我決定使用信號量來確保在讀取之前不會產生新的字母。sem_wait在我的程序中被忽略
問題是我的編寫器進程忽略了sem_wait(讀取),當它的值是0並且它應該等待。它甚至在讀者開始之前完成它的工作。我運行它通過./writer & ./reader
。
我附上了代碼。這裏有一些未使用的元素,因爲它還不是最終版本。然而,問題已經出現。
/* writer.c */
#include <stdio.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <unistd.h>
#include <stdlib.h>
#include <semaphore.h>
int main(int argc, char *argv[])
{
key_t shmkey = 0xF00;
int bytes = sizeof(char)*3 + sizeof(sem_t) * 3;
int shmid;
char* sharedMemory;
sem_t *writing, *reading, *working;
if ((shmid = shmget(shmkey, bytes, IPC_CREAT | IPC_EXCL | 0666)) < 0)
{
shmdt((void*) sharedMemory);
shmctl(shmid, IPC_RMID, NULL);
return 1;
}
if ((sharedMemory = (char*) shmat(shmid, NULL, 0)) == (char*) -1)
{
shmdt((void*) sharedMemory);
shmctl(shmid, IPC_RMID, NULL);
return 1;
}
writing = (sem_t*)(sharedMemory + 3);
reading = writing + 1;
working = reading + 1;
sem_init(writing, 0, 0);
sem_init(reading, 0, 0);
sharedMemory[2] = 'w'; // writer is running
char c;
for(c = 'a'; c <= 'z'; ++c)
{
*sharedMemory = c;
sem_post(writing);
sem_wait(reading);
}
sharedMemory[2] = 'q';
while (sharedMemory[2] != 'w');
sharedMemory[2] = 'q';
shmdt((void*) sharedMemory);
shmctl(shmid, IPC_RMID, NULL);
return 0;
}
與讀者,
/* reader.c */
#include <stdio.h>
#include <stdlib.h>
#include <sys/shm.h>
#include <unistd.h>
#include <stdlib.h>
#include <semaphore.h>
int main(int argc, char *argv[])
{
key_t shmkey = 0xF00;
int bytes = sizeof(char)*3 + sizeof(sem_t) * 3;
int shmid;
char* sharedMemory;
sem_t *writing, *reading, *working;
sleep(1); // wait until writer allocates fresh memory
if ((shmid = shmget(shmkey, bytes, 0666)) < 0)
{
shmdt((void*) sharedMemory);
return 1;
}
if ((sharedMemory = (char*) shmat(shmid, NULL, 0)) == (char*) -1)
{
shmdt((void*) sharedMemory);
return 1;
}
if (sharedMemory[2] != 'w') // is writer running?
{
shmdt((void*) sharedMemory);
return 1;
}
writing = (sem_t*)(sharedMemory + 3);
reading = writing + 1;
working = reading + 1;
//sleep(5); //@REMOVE
char c;
do
{
sem_wait(writing);
c = *sharedMemory;
sem_post(reading);
printf("%c\n", c);
} while (sharedMemory[2] == 'w');
sharedMemory[2] = 'w';
shmdt((void*) sharedMemory);
return 0;
}
該文檔說,sem_init()的第二個參數應該爲非零值,以便在進程之間共享信號量 - 您似乎會調用未定義的行爲。如果你改變了,會發生什麼? – Notlikethat
@Notlikethat它沒有幫助 –
你也應該檢查返回值 - 在失敗閱讀'errno'會告訴你什麼是錯的。 – Notlikethat