对pthread_create和pthread_join的未定义引用

时间:2017-10-15 00:04:32

标签: c linux multithreading linker-errors

我正在尝试构建我的程序,但不断收到相同的错误消息:

undefined reference to pthread_create  
undefined reference to pthread_join

我已经包含了pthread.h,并在我的makefile中使用-pthread编译。

int threadAmount = strtol(nrthr, NULL, 0);
    threadAmount--;

    if(threadAmount > 0){
        pthread_t tids[threadAmount];

        for(int i = 0;i < threadAmount; i++){
            pthread_attr_t attr;
            pthread_attr_init(&attr);
            pthread_create(&tids[i],&attr,search,&t1);
        }

        for(int i = 0;i < threadAmount; i++){
            pthread_join(tids[i],NULL);
        }
    }

我在这里呼叫创建和加入它抱怨的地方。可能是什么问题?

用于构建的makefile:

CC=gcc
CFLAGS= -pthread -std=gnu11 -Wall -Wextra -Werror -Wmissing-declarations -Wmissing-prototypes -Werror-implicit-function-declaration -Wreturn-type -Wparentheses -Wunused -Wold-style-definition -Wundef -Wshadow -Wstrict-prototypes -Wswitch-default -Wunreachable-code

all: mfind

list.o: list.c list.h
    $(CC) -c list.c $(CFLAGS)

mfind.o: mfind.c list.h
    $(CC) -c mfind.c $(CFLAGS) 

mfind: mfind.o list.o
    $(CC) mfind.o list.o -o mfind

clean:
    rm -f *.o mfind

mfind是主程序,list.c是已实施的列表。

2 个答案:

答案 0 :(得分:1)

-pthread不属于CFLAGS。如您所见,所需的库必须位于所有目标文件之后的命令行选项的末尾。由于你有一个makefile,你需要将-pthread放在LDLIBS中。

来自https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html

  

LDLIBS

     

当应该调用链接器时,为编译器提供的库标志或名称,'ld'。 LOADLIBES是LDLIBS的弃用(但仍受支持)替代方案。非库链接器标志(如-L)应包含在LDFLAGS变量中。

答案 1 :(得分:1)

list.o: list.c list.h
    $(CC) -c list.c $(CFLAGS)

mfind.o: mfind.c list.h
    $(CC) -c mfind.c $(CFLAGS) 

mfind: mfind.o list.o
    $(CC) mfind.o list.o -o mfind

看起来您的某些食谱遗失CFLAGS,其中包含-pthread选项。我相信它应该是:

list.o: list.c list.h
    $(CC) $(CFLAGS) -c list.c

mfind.o: mfind.c list.h
    $(CC) $(CFLAGS) -c mfind.c

mfind: mfind.o list.o
    $(CC) $(CFLAGS) mfind.o list.o -o mfind

...

可以CFLAGS输出工件。实际上,当编译器驱动程序驱动链接时,您应该使用相同的CFLAGS(和CXXFLAGS)。您还应该始终使用编译器驱动程序,因为它负责将选项(如-pthread-fopenmp-fsanitize=undefined)转换为链接器的正确选项和库。

如果有兴趣,这是GNUmake使用的默认规则:Catalogue of Built-In Rules。请注意*.c个文件的配方包括CFLAGS

  

编译C程序

     

n.o是使用n.c形式的食谱从$(CC) $(CPPFLAGS) $(CFLAGS) -c自动生成的。

如果您使用GNU Make手册中的以下内容,则还应将-pthread添加到LDFLAGS。但我建议您按照编译器人员告诉我们的内容,即通过编译器驱动程序驱动链接。

  

关联单个目标文件

     

n是通过运行链接器(通常是n.o自动生成的   通过C编译器调用ld)。使用的精确配方是$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)