私のプログラムにはpthread.h
とsemaphore.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
ヘッダファイル/コンパイルとライブラリ/リンクには違いがあります。あなたは明らかに後者を台無しにしました。 – Olaf
リンクフラグが何であるか教えてください。特に、 '-pthread'をビルドに含めていますか? – kaylum
それは問題でした、そのリンカフラグを忘れました。あなたがそれを答えるなら、私はそれを受け入れるでしょう。 – Adam