Я изучаю, как использовать функции Unix для программирования на C, чтобы я мог программировать функциональность Семафора на ноже (без pthreads), но в настоящее время я застрял. В man-страницах мне было предложено включить определенные файлы заголовков для использования интересующих функций (например, malloc, tsleep, wakeup и т. Д.), Но когда я пытаюсь запустить свою программу с помощью заголовков и вызовов методов, я получаю следующие ошибки:'undefined reference to' [OpenBSD 3.5 system defined method]
/tmp//ccg29960.o: In function `allocate_semaphore':
/tmp//ccg29960.o(.text+0x28d): undefined reference to `simple_lock_init'
/tmp//ccg29960.o: In function `down_semaphore':
/tmp//ccg29960.o(.text+0x2fb): undefined reference to `tsleep'
/tmp//ccg29960.o: In function `up_semaphore':
/tmp//ccg29960.o(.text+0x3b5): undefined reference to `wakeup'
/tmp//ccg29960.o: In function `free_semaphore':
/tmp//ccg29960.o(.text+0x43b): undefined reference to `simple_lock'
/tmp//ccg29960.o(.text+0x4af): undefined reference to `simple_unlock'
collect2: ld returned 1 exit status
Соответствующий код приведен ниже:
//#include <stdio.h>
//#include <stdlib.h>
#include <sys/errno.h>
#include <sys/queue.h>
//#include <sys/time.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/proc.h>
#include <sys/malloc.h>
#include <sys/lock.h>
struct entry
{
pid_t id;
SIMPLEQ_ENTRY(entry) next;
} *np;
typedef struct
{
const char* name;
pid_t process;
pid_t p_process; //parent process
int count;
SIMPLEQ_HEAD(queuehead,entry) head;
struct simplelock *slock;
} named_semaphore;
named_semaphore* s_list[64];
int num_semaphores = 0;
int main()
{
//lockinit(0, 0, 0,0, 0);
printf("Hello world\n");
return 0;
}
//... irrelevant code elided
int allocate_semaphore(const char* name, int initial_count)
{
int num_elements, i;
named_semaphore *new_s;
//perform initial checks before creating a new semaphore
//make sure the given name is an acceptable length
num_elements = sizeof(name)/sizeof(*name);
if (num_elements > 32)
{
return ENAMETOOLONG;
}
//make sure the given name is unique to this process
for (i = 0; i < num_semaphores; i++)
{
if (s_list[i]->process == getpid() && strcmp(s_list[i]->name, name))
{
return EEXIST;
}
}
//make sure there are no more than 64 semaphores active
if (num_semaphores >= 64)
{
return ENOMEM;
}
//create a new semaphore and add it to the collection
new_s = (named_semaphore*) malloc(sizeof(named_semaphore), 0, 0);
new_s->name = name;
new_s->process = getpid();
new_s->p_process = getppid();
new_s->count = initial_count;
s_list[num_semaphores] = new_s;
++num_semaphores;
//initialize the waiting queue
SIMPLEQ_INIT(&(new_s->head));
//initialize its lock
simple_lock_init(new_s->slock);
//need to handle negative initial_count somehow
return (0);
}
int down_semaphore(const char* name)
{
named_semaphore* s;
s = getSemaphore(name);
if (s == NULL)
{
return (ENOENT);
}
s->count = (s->count) - 1;
if (s->count < 0)
{
//put process to sleep
tsleep(getpid(), getpriority(), 0, 0);
//add process to waiting queue
np = (struct entry *) malloc(sizeof(struct entry));
np->id = getpid();
SIMPLEQ_INSERT_TAIL(&(s->head), np, next);
}
return 0;
}
int up_semaphore (const char* name)
{
named_semaphore* s;
s = getSemaphore(name);
if (s == NULL)
{
return (ENOENT);
}
s->count = (s->count) + 1;
if (s->count <= 0)
{
//wakeup longest waiting process
wakeup((SIMPLEQ_FIRST(&(s->head)))->id);
//remove process from waiting queue
SIMPLEQ_REMOVE_HEAD(&(s->head), np, next);
free(np);
}
return 0;
}
int free_semaphore(const char* name)
{
named_semaphore* s;
s = getSemaphore(name);
if (s == NULL)
{
return (ENOENT);
}
simple_lock(s->slock);
while ((np = SIMPLEQ_FIRST(&(s->head))) != NULL)
{
//wakeup the process and return ECONNABORTED
//wakeup(getSemaphore(np->id));
SIMPLEQ_REMOVE_HEAD(&(s->head), np, next);
free(np);
}
free(s);
simple_unlock(s->slock);
}
Я не сделал изменения/фиксации логики моей общей программы (например, блокировка() ИНГ происходит только в 1/3 предполагаемой методы), но было бы замечательно понять, почему я получаю свою текущую ошибку, чтобы я знал, как исправить подобные в будущем.
Мне кажется, что методы не распознают их заголовочные файлы или что мне не хватает необходимой информации, чтобы эти два могли общаться.
Чтобы исправить ошибки, я попытался переставить и прокомментировать перечисленные файлы заголовков, а также переименовать вызовы метода заглавными буквами, как они были представлены в документации файла заголовка.
Любая помощь или проницательность оценивается, и заранее заблаговременно!