本章将进一步深入理解进程,了解如何使用多个控制线程(简单得说就是线程)在单进程环境中执行多个任务。
线程概念
每个线程都包含有表示执行环境所必须的信息:线程ID、一组寄存器值、栈、调度优先级和策略、信号屏蔽字、errno变量以及线程私有数据。
一个进程的所有信息对该进程的所有线程都是共享的,包括可执行程序的代码、程序的全局内存和堆内存、栈以及文件描述符。
线程标识
每个线程都有一个线程ID,线程ID只有在它所属的进程上下文中才有意义。
可以使用下面函数来对两个线程ID进行比较
#include <pthread.h>
int pthread_equal(pthread_t tid1,pthread_t tid2);
可以通过pthread_self函数获得自身的线程ID
#include <pthread.h> pthread_t pthread_self(void);
线程创建
#include <pthread.h> int pthread_create(pthread_t *restrict tidp,const pthread_attr_t *restrict attr,void *(*start_rtn)(void *),void *restrict arg);
当pthread_create成功返回时,新创建线程的线程ID会被设置成tidp指向的内存空间。
attr属性用于定制各种不同的线程属性。
新创建的线程从start_rtn函数的地址开始运行,该函数只有一个无类型指针参数arg。
下面程序将演示线程的创建,打印出进程ID、新线程的线程ID以及初始线程的线程ID:
1 #include "apue.h" 2 #include <pthread.h> 3 4 pthread_t ntid; 5 6 void 7 printids(const char *s) 8 { 9 pid_t pid; 10 pthread_t tid; 11 12 pid = getpid(); 13 tid = pthread_self(); 14 printf("%s pid %lu tid %lu (0x%lx)\n", s, (unsigned long)pid, 15 (unsigned long)tid, (unsigned long)tid); 16 } 17 18 void * 19 thr_fn(void *arg) 20 { 21 printids("new thread: "); 22 return((void *)0); 23 } 24 25 int 26 main(void) 27 { 28 int err; 29 30 err = pthread_create(&ntid, NULL, thr_fn, NULL); 31 if (err != 0) 32 err_exit(err, "can't create thread"); 33 printids("main thread:"); 34 sleep(1); 35 exit(0); 36 }