Linux在用fork创建进程时,为子进程申请了堆栈、BSS区、全局变量、和代码段等资源。而用pthread_create创建线程时,用户空间分配的资源比线程少得多。可以说,线程就是轻量级的进程。
1.函数 pthread_create()用来创建一个新的线程。其函数声明如下:
1 /*come from /usr/include/pthread.h*/ 2 extern int pthread_create (pthread_t *__restrict __newthread, 3 __const pthread_attr_t *__restrict __attr, 4 void *(*__start_routine) (void *), 5 void *__restrict __arg) __THROWNL __nonnull ((1, 3));
第一个参数用来存储线程的ID,参数为指向线程ID的指针。创建成功,返回新线程ID;_restrict 是C99定义的新标准关键字,主要用来提高编译效率。
第二个参数用来设置线程属性,主要设置与栈相关的属性。一般情况下,此参数设置为NULL,新的线程将使用系统默认的属性。
第三个参数是线程运行的代码起始地址。
第四个参数是运行函数的参数地址,如果需要传入多个参数,需要使用结构体。
示例:
1 #include <pthread.h> 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <unistd.h> 6 #include <sys/syscall.h> 7 8 struct message 9 { 10 int i; 11 int j; 12 }; 13 14 void *hello (struct message *str); 15 16 int main(int argc, char* argv[]) 17 { 18 struct message test; 19 pthread_t thread_id; 20 test.i = 10; 21 test.j = 20; 22 /*create thread*/ 23 pthread_create(&thread_id, NULL, (void *) *hello, &test); 24 printf("parent, the tid = %lu, pid = %ld\n",pthread_self(),syscall(SYS_gettid)); 25 pthread_join(thread_id,NULL); 26 sleep(1); 27 return 0; 28 } 29 30 void *hello (struct message *str) 31 { 32 printf("child, the tid = %lu, pid = %ld\n",pthread_self(),syscall(SYS_gettid)); 33 printf("the arg.i is %d, arg.j is %d\n",str->i, str->j); 34 }
2.线程的退出和等待:
线程的退出函数声明如下:
extern void pthread_exit (void *__retval) __attribute__ ((__noreturn__));
此函数只有一个参数,即线程退出状态。
等待线程:
为了同步线程,一般主线程都会等待子线程结束,显式的等待某线程结束。可以调用pthread_join实现。其函数声明如下:
extern int pthread_join (pthread_t __th, void **__thread_return);
第一个参数是被等待的线程的ID,第二个参数为用户定义的指针,指向一个保存等待线程的完整退出状态的静态区域,它可以用来存储被等待线程的返回值。
线程的独立:
如果要设置某个线程为独立线程,则可以调用pthread_detach实现。声明如下:
extern int pthread_detach (pthread_t __th)
示例代码:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <pthread.h> 4 #include <string.h> 5 #include <unistd.h> 6 #include <sys/syscall.h> 7 8 void *helloworld(char* arg); 9 10 int main(int argc, char* argv[]) 11 { 12 int error; 13 int *temptr; 14 pthread_t thread_id; 15 /*create thread*/ 16 pthread_create(&thread_id,NULL,(void)helloworld,"hello,world"); 17 printf("*p = %u, p = %u\n",(unsigned int)*helloworld,(unsigned int) helloworld); 18 19 /*wait for child thread terminating*/ 20 pthread_join(thread_id,(void **)&temptr); 21 22 printf("temp = %x, *temp = %c\n",(unsigned)temptr,*temptr); 23 *temptr = 'd'; 24 printf("%c\n",*temptr); 25 free(temptr); 26 return 0; 27 } 28 29 void *helloworld(char *arg) 30 { 31 int *p; 32 p = (int*)malloc(10*sizeof(int)); 33 printf("the message is %s\n",arg); 34 printf("the child id is %u\n",pthread_self()); 35 memset(p,'c',10); 36 printf("p = %x\n",(unsigned)p); 37 /*thread exit*/ 38 pthread_exit(p); 39 }