【发布时间】:2016-07-06 00:10:30
【问题描述】:
我在我的程序中使用了pthread.h 和semaphore.h,并且已经包含了这些库。但是,似乎虽然我可以调用一些线程函数(如pthread_exit())并创建信号量变量,但我不能使用其他函数如sem_wait。我收到了来自 Eclipse 的undefined reference 投诉。知道为什么会这样吗?在下面的代码中,void *thread1(void* v) 中的 semaphore.h 函数不起作用。错误日志在代码下方。
#define _GNU_SOURCE
#include <time.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <fcntl.h>
#include <semaphore.h>
#include <pthread.h>
typedef long long ll;
sem_t mutex;
int num=0;
void A(void);
void handler(void *ptr)
{
pthread_exit(0);
}
double calculateAverage(double *arr, int len)
{
double average=0.00;
//first sum up all entries
for(int i=0;i<len;i++)
{
average+=arr[i];
}
return average;
}
static inline ll timespec_to_ns(const struct timespec *tv)
{
return ((ll) tv->tv_sec * 1000000000) + tv->tv_nsec;
}
ll beginMeasureTime() {
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
return timespec_to_ns(&t);
}
ll endMeasureTime(ll beginTime) {
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
return timespec_to_ns(&t)-beginTime;
}
ll measureFunctionCall(int n) {
ll beginTime=beginMeasureTime();
for(int i=0;i<n;i++) {
A();
}
return endMeasureTime(beginTime);
}
ll measureSyscall(int n) {
ll beginTime=beginMeasureTime();
for(int i=0;i<n;i++) {
syscall(SYS_getpid);
}
return endMeasureTime(beginTime);
}
ll measureProcessSwitch(int n) {
int p[2];
int p1[2];
char arr;
ll t=-1;
// 0 for read 1 for writing
if(pipe(p)<0) {
perror("pipe");
return -1;
}
if(pipe(p1)<0) {
perror("pipe");
goto out1;
}
int pid=fork();
if(pid<0) {
perror("fork");
goto out2;
}
if(pid==0)
{
while(1)
{
if(read(p[0],&arr,1)<=0) _exit(1);
if(write(p1[1],&arr,1)<=0) _exit(1);
}
_exit(0);
}
ll beginTime=beginMeasureTime();
for(int i=0;i<n;i++){
if(write(p[1],&arr,1)<=0) {
perror("write");
goto out2;
}
if(read(p1[0],&arr,1)<=0) {
perror("read");
goto out2;
}
}
t=endMeasureTime(beginTime);
out2:
close(p1[0]);
close(p1[1]);
out1:
close(p[0]);
close(p[1]);
return t;
}
typedef struct {
sem_t s1; //parent->child
sem_t s2; //child->parent
int abort;
} info;
void* thread1(void* v) {
info* inf=(info*)v;
while(1)
{
if( sem_wait(&inf->s1) < 0) break;
if(inf->abort) break;
sem_post(&inf->s2);
}
return NULL;
}
ll measureThreadSwitch(int n) {
info inf;
inf.abort=0;
ll t=-1;
// 0 for read 1 for writing
if(sem_init(&inf.s1,0,0)<0) {
perror("sem_init");
return -1;
}
if(sem_init(&inf.s2,0,0)<0) {
perror("sem_init");
goto out1;
}
pthread_t th;
if(pthread_create(&th,NULL,&thread1,&inf)<0) {
perror("pthread_create");
goto out2;
}
ll beginTime=beginMeasureTime();
for(int i=0;i<n;i++){
if(sem_post(&inf.s1)<0) {
perror("sem_post");
goto out3;
}
if(sem_wait(&inf.s2)<0) {
perror("sem_wait");
goto out3;
}
}
t=endMeasureTime(beginTime);
out3:
//thread is still running; need to signal to it to exit
//and wait for it to exit
inf.abort=1;
sem_post(&inf.s1);
pthread_join(th,NULL);
out2:
sem_destroy(&inf.s2);
out1:
sem_destroy(&inf.s1);
return t;
}
int main(int argc, char **argv)
{
if(argc <2)
{
printf("You entered less than two arguements\n");
exit(-2);
}
if(argv[1] <0)
{
printf("you entered a negative argument\n");
exit(-1);
}
int n=(atoi(argv[1]));
printf("function call: %lld ns\n",measureFunctionCall(n)/n);
printf("system call: %lld ns\n",measureSyscall(n)/n);
printf("process switching: %lld ns\n",measureProcessSwitch(n)/n);
printf("thread switching: %lld ns\n",measureThreadSwitch(n)/n);
}
/home/anb1/workspace/test/Debug/../src/test.c:123: undefined reference tosem_wait'
/home/anb1/workspace/test/Debug/../src/test.c:125:未定义对sem_post'
./src/test.o: In functionmeasureThreadSwitch'的引用:
/home/anb1/workspace/test/Debug/../src/test.c:134:未定义对sem_init'
/home/anb1/workspace/test/Debug/../src/test.c:138: undefined reference tosem_init'的引用
/home/anb1/workspace/test/Debug/../src/test.c:143:未定义对pthread_create'
/home/anb1/workspace/test/Debug/../src/test.c:150: undefined reference tosem_post'的引用
/home/anb1/workspace/test/Debug/../src/test.c:154:对sem_wait'
/home/anb1/workspace/test/Debug/../src/test.c:164: undefined reference tosem_post'的未定义引用
/home/anb1/workspace/test/Debug/../src/test.c:165:未定义对pthread_join'
/home/anb1/workspace/test/Debug/../src/test.c:167: undefined reference tosem_destroy'的引用
/home/anb1/workspace/test/Debug/../src/test.c:169:未定义对sem_destroy'
collect2: error: ld returned 1 exit status
make: *** [test] Error 1
的引用
【问题讨论】:
-
头文件/编译和库/链接之间存在差异。你显然搞砸了后者。
-
您需要告诉我们链接标志是什么。特别是,您是否在构建中包含
-pthread? -
那是问题所在,忘记了链接器标志。如果你做出这样的回答,我会接受。