Это моя первая попытка семафоров и потоков.
Я построил этот код из примеров и страниц руководства, найденных в сети.
У меня есть два сомнения с этим кодом.
Почему я получаю ошибку шины всякий раз, когда я пробую semctl (я знаю, что это корень проблемы из-за того, что строка отладки 3 не печатается) и как ее предотвратить?
Почему я не могу заблокировать критическую секцию, несмотря на удаление semctl ()?
Я пытаюсь выполнить следующий код:
#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/sem.h>
#define NUM 3
char c='a';
int semId=-1;
struct sembuf lockOperation = { 0, -1, 0};
struct sembuf unlockOperation = { 0, -1, 0};
void* PrintLetter()
{
int rc;
rc=semop(semId, &lockOperation, 1);
if(rc)
{
printf("\n Unable to lock\n");
exit(1);
}
printf("%c",c); //CRITICAL SECTION
c=c+1; //CRITICAL SECTION
rc = semop(semId, &unlockOperation, 1);
if(rc)
{
printf("\n Unable to unlock\n");
exit(1);
}
pthread_exit(NULL);
}
int main()
{
pthread_t threads[NUM];
int rc=1;
long t;
printf("debug line 1\n");
semId = semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL);
if( semId == -1)
{
printf("\n Error in making the sem\n");
exit(1);
}
printf("debug line 2\n");
rc = semctl(semId, 0, SETVAL, (int)1); // Comment from here
if(rc)
{
printf("\n Unable to set val to 1\n");
exit(1);
} ////////////////////////////////// till here
printf("debug line 3\n");
for(t=0; t<NUM; t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintLetter, NULL);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
sleep(3);
}
pthread_exit(NULL);
}
Примечание:
Я добавил следующее в код после предложения:
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux specific) */
};
Также добавлено следующее:
union semun s_u;
s_u.val=1;
Изменена строка semctl на
rc = semctl(semId, 0, SETVAL, s_u);
и сделал все проверки rc:
if(rc == -1)
Строка semctl () по-прежнему не выполняется успешно.
Errno теперь заявляет:
В доступе отказано
ОБНОВЛЕНИЕ : я могу избавиться от ошибки «Отказано в доступе», используя следующее изменение:
semId = semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL|0660);
Теперь новая проблема в том, что я не могу напечатать «abc» на консоли.
Программа просто печатает "а" и зависает. Не уверен почему.
Окончательное обновление :
Я запутался в коде разблокировки:
я использовал -1 вместо 1
Вот новый код:
struct sembuf unlockOperation = { 0, 1, 0};
Благодарю всех за помощь и терпение.