'undefined reference to' [OpenBSD 3.5系统定义方法]

'undefined reference to' [OpenBSD 3.5 system defined method]

我一直在学习如何使用 Unix 函数在 C 中编程,以便我可以从头开始(没有 pthreads)编程信号量功能,但我目前被卡住了。手册页告诉我要包含特定的头文件以使用感兴趣的函数(例如 malloc、tsleep、wakeup 等),但是当我尝试 运行 我的程序使用头文件和方法调用时,我收到以下错误:

/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 );
}

我还没有完成 modifying/fixing 我整个程序的逻辑(例如,锁定()只发生在预期方法的 1/3 中),但如果能理解为什么我我收到了我当前的错误,以便我知道将来如何修复类似的错误。

对我来说,这些方法似乎无法识别它们的头文件,或者我缺少一条必需的信息,以便两者可以通信。

为了修复这些错误,我尝试重新排列和注释掉列出的头文件,并用大写字母重命名方法调用,就像它们在头文件文档中一样。

感谢任何帮助或见解,在此先感谢您!

您阅读的手册页...那些是第 9 节,不是吗?第 9 节用于内核编程。除非您的代码在内核中,否则您不能调用这些函数。