|
创建线程与线程退出
创建线程通过 pthread_create() 来完成:
#include <pthread.h>
int pthread_create ( pthread_t *thread, pthread_attr_t *attr, void * (*start_routine) (void *), void *arg ); 参数含义:
thread : 该参数是一个 pthread_t 类型指针,当线程创建成功时,用来返回创建的线程 ID 。
attr : 该参数用于指定线程的属性,一般没什么特殊需求就用 NULL,表示使用默认属性。
start_routine : 该参数为一个普通的函数指针( void * (*) (void *) ),指向线程创建后要调用的函数。这个被线程调用的函数也称为线程函数。
arg : 该参数指向传递给线程函数的参数。
程序举例:
| #include <stdio.h> | | /*一直往 stderr 上打印x,参数这里没用.*/ | void *print_xs(void *unused) | { | while(1) | fputc('x', stderr); | return NULL; | } | | int main() | { | pthread_t thread_id; | /*创建新进程,新进程将运行 print_xs 函数*/ | pthread_create(&thread_id, NULL, &print_xs, NULL); | /*一直在 stderr 上打印 o*/ | while(1) | fputc('o',stderr); | return 0; | } |
测试程序2:
#include <pthread.h>
#include <stdio.h>
/*要传递给线程函数的参数*/
struct char_print_parms
{
char character; /*要打印的字符*/
int count; /*打印字符的次数*/
}
void *char_print (void *parameters)
{
struct char_print_parms *p = (struct char_print_parms*) parameters;
int i;
for(i = 0; i < p->count; i++)
fputc(p->character, stderr);
return NULL;
}
int main()
{
pthread_t pthread1_id;
pthread_t pthread2_id;
struct char_print_parms thread1_args;
struct char_print_parms thread2_args;
thread1_args.character = 'x';
thread1_args.count = 30000;
pthread_create(&pthread1_id, NULL, &char_print, &thread1_args);
thread1_args.character = 'o';
thread1_args.count = 20000;
pthread_create(&pthread2_id, NULL, &char_print, &thread2_args);
printf("hello world\n");
return 0;
} 说明:例 2 中有个严重的 bug 。main 主线程建立了线程本地变量参数,这个参数是结构体类型( thread1_args 和 thread2_args )。接着,把指向这两个结构体的指针传递给了主线程所创建的子线程。由输出可见,线程的工作还没做完( 没有输出预设数目的字符 )甚至还没开始时,主线程已经退出。这时候,整个进程将终止,此时进程中的线程也将终止。因此,在主线程中不能过早的从 main() 函数返回的。
如果在 main() 函数里使用 pthread_exit() 函数,则仅仅是主线程消亡,进程却不会结束,进程内的其他线程也不会终止,知道所有线程结束,进程才会结束。如在上面程序的 printf("hello world\n"); 语句后面添加一句 pthread_exit(NULL);
那么从输出可见,输出的前半段,子线程输出自己的字符'x'或'o',经过系统的调用,中间轮换到了主线程执行,这时主线程输出了 "hello world" 。此后因为主线程调用了 pthread_exit() 函数,主线程消亡,经由操作系统调度,子进程继续工作,直到玩成自己的任务为止,最后才结束退出。 |
|