11

我用 C 编写了一个多线程服务器程序,它回显客户端发送的所有数据。

最初,我poll()在程序中使用函数来检测POLLRDHUP事件,为此我定义了_GNU_SOURCE宏(此事件在此处定义)。

后来我更新了我的代码并删除poll()了函数,但是我忘记了删除_GNU_SOURCE宏。

现在我的代码终于完成了(而且发布的时间有点长,超过 250 行)。在删除宏之前,我正在使用以下方法编译我的程序:

gcc multi_thread_socket_v4.c -Wall -Werror -g -lpthread -o multi_thread_socket

它工作正常:没有错误,没有警告

在我删除宏定义并使用相同的命令行编译后,gcc 的输出是:

multi_thread_socket_v4.c: In function ‘main’:
multi_thread_socket_v4.c:194: warning: implicit declaration of function ‘pthread_mutexattr_settype’
multi_thread_socket_v4.c:194: error: ‘PTHREAD_MUTEX_ERRORCHECK’ undeclared (first use in this function)
multi_thread_socket_v4.c:194: error: (Each undeclared identifier is reported only once
multi_thread_socket_v4.c:194: error: for each function it appears in.)

我已经包含了所有必需的库,因为它最初运行良好。

我偷看了pthread.h一下/usr/include/pthread.h,发现了这个:

/* Mutex types.  */
enum
{
  PTHREAD_MUTEX_TIMED_NP,
  PTHREAD_MUTEX_RECURSIVE_NP,
  PTHREAD_MUTEX_ERRORCHECK_NP,
  PTHREAD_MUTEX_ADAPTIVE_NP
#ifdef __USE_UNIX98
  ,
  PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP,
  PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
  PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
  PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
#endif
#ifdef __USE_GNU
  /* For compatibility.  */
  , PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_TIMED_NP
#endif
};

还有这个:

#ifdef __USE_UNIX98
/* Return in *KIND the mutex kind attribute in *ATTR.  */
extern int pthread_mutexattr_gettype (__const pthread_mutexattr_t *__restrict
                      __attr, int *__restrict __kind)
     __THROW __nonnull ((1, 2));

/* Set the mutex kind attribute in *ATTR to KIND (either PTHREAD_MUTEX_NORMAL,
   PTHREAD_MUTEX_RECURSIVE, PTHREAD_MUTEX_ERRORCHECK, or
   PTHREAD_MUTEX_DEFAULT).  */
extern int pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind)
     __THROW __nonnull ((1));

在这里检查以检查是否__USE_UNIX98是功能测试宏,但它不存在。

所以请帮助我理解错误的原因,因为显示错误的函数和宏是在 POSIX 标准中定义的gcc。我不知道需要关于我的问题的更多信息,所以请告诉我,我会更新我的问题。

4

3 回答 3

8

你应该使用

#define _POSIX_C_SOURCE 200112L

如果您想使用 POSIX 功能,例如 pthread_mutexattr_settype ...请参阅http://pubs.opengroup.org/onlinepubs/007904975/functions/xsh_chap02_02.html

另一种可能是

#define _XOPEN_SOURCE 700

http://man7.org/linux/man-pages/man7/feature_test_macros.7.htmlhttp://pubs.opengroup.org/onlinepubs/9699919799/

设置 _GNU_SOURCE 包括 POSIX 和许多其他定义。

PS我希望包括<pthread.h>includes <features.h>,默认情况下将_POSIX_C_SOURCE定义为200112L,但您可能已经定义了一些覆盖它的东西......有关符号及其用法的详细信息,请参阅系统上的/usr/include/features.h .

于 2013-08-22T09:41:06.630 回答
1

不是,您的问题可能出在其他地方。

我刚刚编译了一个简单的程序,内容如下:

#include <pthread.h>

int main(int argc, char **argv)
{
    pthread_mutexattr_t attr;

    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);

    return 0;
}

这与gcc -pthread -Wall -Werror a.c.

您的程序的另一部分可能会导致这种情况,例如。做一些愚蠢的事情,比如定义_PTHREAD_H,或者其他一些小的破坏。

您可能想尝试通过使用deltacreduce 之类的工具来获得最小的测试用例,这可能会使问题变得明显。

于 2013-08-22T09:40:17.130 回答
0

当您使用库(例如 2.1.x)时,您应该使用

#define __USE_UNIX98

使用以“__”开头的宏通常不是一个好主意,但有时这是唯一的方法......另见此讨论

于 2016-03-22T09:35:17.103 回答