开发多线程程序
开发多线程程序与开发带有多个进程的程序类似。 程序的开发也由编译和调试代码组成。
编译多线程程序
- 必需的头文件
- 调用用来生成多线程程序的编译器。
头文件
所有使用线程库的原型、宏和其他定义均在 pthread.h 头文件中,该文件在 /usr/include 目录下。 pthread.h 头文件必须包含在每个使用线程库的源文件中。
pthread.h 头包含 unistd.h 头,后者提供以下全局定义:
- _POSIX_REENTRANT_FUNCTIONS
- 指定应该是重入的所有函数。 多个头文件使用此符号定义辅助重入子例程,例如:localtime_r 子例程。
- _POSIX_THREADS
- 表示 POSIX 线程 API。 此符号用来检查 POSIX 线程 API 是否可用。 宏或者子例程可能使用其他方法定义,这取决于是否使用了 POSIX 或者某些其他线程 API。
pthread.h 文件还包含 errno.h,在后者中,errno 全局变量重新定义为特定于线程。 因此,errno 标识在多线程程序中不再是左值。
调用编译器
- xlc_r
- 用 ansi 的缺省语言级别调用编译器
- cc_r
- 用扩展的缺省语言级别调用编译器
这些命令可确保使用适当的选项和库,以符合单一 UNIX 规范第 2 版。 POSIX 线程规范 1003.1c 是 单一 UNIX 规范 V 2的子集。
- libpthreads.a
- 线程库
- libc.a
- 标准 C 库
cc_r -o foo foo.c对 POSIX 1003.1c Draft 7 调用编译器
AIX®为 Draft 7 应用程序提供源代码兼容性。 建议开发者将他们的线程应用程序移植到最新标准。
- xlc_r7
- 用 ansi 的缺省语言级别调用编译器
- cc_r7
- 用扩展的缺省语言级别调用编译器
- libpthreads_compat.a
- Draft 7 兼容性线程库
- libpthreads.a
- 线程库
- libc.a
- 标准 C 库
要实现源代码兼容性,请使用编译器伪指令 _AIX_PTHREADS_D7。 还需要按照下面的顺序链接库:libpthreads_compat.a、libpthreads.a 和 libc.a。 大多数用户不需要知道这些信息,因为命令将提供必要的选项。 为那些没有最新 AIX 编译器的用户提供了这些选项。
Porting draft 7 applications to the &Symbol.unixspec;
- 较小的 errno 差别。 最普遍的是使用 ESRCH 表示找不到指定的 pthread。 Draft 7 对此故障通常返回 EINVAL。
- 创建 pthread 时,缺省状态是可连接。 这是很大的更改,因为如果忽略会导致内存泄漏。
- 缺省 pthread 调度参数是 scope。
- pthread_yield 子例程被 sched_yield 子例程替换。
- 与互斥锁关联的各种不同的调度策略稍有不同。
多线程程序的内存要求
| 数据模型 | -bmaxdata | 最大 Pthread 数 |
|---|---|---|
| 小数据 | 不适用 | 1084 |
| 大数据 | 0x10000000 | 2169 |
| 大数据 | 0x20000000 | 4340 |
| 大数据 | 0x30000000 | 6510 |
| 大数据 | 0x40000000 | 8681 |
| 大数据 | 0x50000000 | 10852 |
| 大数据 | 0x60000000 | 13022 |
| 大数据 | 0x70000000 | 15193 |
| 大数据 | 0x80000000 | 17364 |
多线程程序的示例
#include <pthread.h> /* include file for pthreads - the 1st */
#include <stdio.h> /* include file for printf() */
#include <unistd.h> /* include file for sleep() */
void *Thread(void *string)
{
while (1)
printf("%s\n", (char *)string);
pthread_exit(NULL);
}
int main()
{
char *e_str = "Hello!";
char *f_str = "Bonjour !";
pthread_t e_th;
pthread_t f_th;
int rc;
rc = pthread_create(&e_th, NULL, Thread, (void *)e_str);
if (rc)
exit(-1);
rc = pthread_create(&f_th, NULL, Thread, (void *)f_str);
if (rc)
exit(-1);
sleep(5);
/* usually the exit subroutine should not be used
see below to get more information */
exit(0);
}初始线程(执行 main 例程)创建两个线程。 两个线程有相同的入口点例程(Thread 例程),但是参数不同。 参数是指向要显示的字符串的指针。
调试多线程程序
多线程程序的核心文件要求
chdev -l sys0 -a fullcore=true每个单独的 pthread 都会增加生成的核心文件的大小。 pthread 需要的核心文件空间量包括堆栈大小,用户可以使用 pthread_attr_setstacksize 子例程来控制堆栈大小。 对于使用 NULL pthread 属性创建的 pthread,32 位进程中的每一个 pthread 会使核心文件的大小增加 128 KB,64 位进程中的每一个 pthread 会使核心文件的大小增加 256 KB。