2016-03-19 8 views
0

私のプログラムにはpthread.hsemaphore.hが使用されていて、これらのライブラリが含まれています。しかし、スレッド関数(pthread_exit()など)を呼び出してセマフォ変数を作成することはできますが、sem_waitなどの他の関数は使用できません。私はEclipseからundefined referenceの苦情を受け取ります。なぜこれが起こっているのか?以下のコードでは、semaphore.hの機能はvoid *thread1(void* v)には機能しません。エラーログはコードの下にあります。ライブラリは見た目に一部分しか含まれていませんが、CとEclipse

#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 to sem_wait ' /home/anb1/workspace/test/Debug/../src/test.c:125:sem_post' ./src/test.o: In function measureThreadSwitchへの未定義参照': /ホーム/ ANB1 /ワークスペース/テスト/デバッグ/../ src/test.c:134:未定義参照sem_init' /home/anb1/workspace/test/Debug/../src/test.c:138: undefined reference to sem_init ' /home/anb1/workspace/test/Debug/../src/test.c:143:未定義参照pthread_create' /home/anb1/workspace/test/Debug/../src/test.c:150: undefined reference to sem_post' /ホーム/ anb1/workspace/test/Debug /../ src/test.c:154:未定義参照sem_wait' /home/anb1/workspace/test/Debug/../src/test.c:164: undefined reference to sem_post ' /home/anb1/workspace/test/Debug/../src/test.c:165:未定義の参照pthread_join' /home/anb1/workspace/test/Debug/../src/test.c:167: undefined reference to sem_destr OY」 /home/anb1/workspace/test/Debug/../src/test.c:169:あなたはあなたのプログラムが正しいヘッダファイルを含めることによって、コンパイル作らsem_destroy' collect2: error: ld returned 1 exit status make: *** [test] Error 1

+1

ヘッダファイル/コンパイルとライブラリ/リンクには違いがあります。あなたは明らかに後者を台無しにしました。 – Olaf

+1

リンクフラグが何であるか教えてください。特に、 '-pthread'をビルドに含めていますか? – kaylum

+0

それは問題でした、そのリンカフラグを忘れました。あなたがそれを答えるなら、私はそれを受け入れるでしょう。 – Adam

答えて

1

に未定義の参照が、あなたはそれリンクしなければなりません正しくhttps://www.eclipse.org/forums/index.php/t/332260/にアクセスしてください。これはEclipseで行う必要があることを反映しています。あなたが含める必要があるものはpthreadライブラリです。

関連する問題