本帖最后由 yuanlai2010 于 2014-9-12 08:37 编辑
POSIX线程基础篇
参与Helper2416开发板助学计划心得
使用NPTL线程库实现
线程的定义:
在一个程序中的多个执行路线就叫做线程,线程是一个进程内的一个控制序列。
也就是说,进程是由一个或多个线程组成的,线程是程序执行的最小单位。
线程与进程的创建过程比较:
当进程执行fork调用时,将创建出该进程的一个新副本,这个新进程拥有自己的变量和自己的PID,它的时间调度也是独立的,它的执行几乎完全独立于父进程。
当在进程中创建一个新线程时,新的执行线程将拥有自己的栈(拥有自己的局部变量。),但与它的创建者共享全局变量、文件描述符、信号处理函数和当前目录状态。
可以这样理解:线程其实就是一个特殊的函数,当有多个线程的时候,这些特殊的函数可以同时被CPU执行
线程的优点缺点:
优点:
1:让程序看起来是在同时处理多件事情(多任务)。
2:线程之间的切换需要操作系统做的工作比进程之间的切换少的多,因此多个线程对资源的需求要远小于多个进程。
缺点:
1:基于线程的程序设计相当复杂,且容易出错。
2:在单核处理器上并不能体现出线程的优势。
线程编程基础:
线程有一套完整的与其有关的函数库调用,它们中的绝大多数函数名都以pthread_开头。为了使用这些函数库调用,我们必须定义宏_REENTRANT,在程序中包含头文件pthread.h,并在编译程序时需要要用选项-lpthread来链接线程库。
编译示例:gcc-D_REENTRANT thread0.c -othread -lpthread
int pthread_create(pthread_t *thrad, pthread_attr_t *attr, void*(*start_routine)(void *), void *arg);
void pthread_exit(void *retval);
int pthread_join(pthread_t thread, void **thread_return);
pthread_create
函数原型:int pthread_create(pthread_t *thrad, pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg);
函数功能:创建一个新线程。
函数返回:调用成功返回0,调用失败返回错误代码。
参数说明:
第一个参数*thread,是指向pthread_t类型数据的指针,线程被创建时,这个指针指向的变量中将被写入一个标识符,可以通过此标识符来引用新线程。
第二个参数*attr,用于设置线程的属性,一般不需要设置,通常设置此参数为NULL。
第三个参数void*(*start_routine)(void *),即线程将要启动执行的函数,
第四个参数*arg,传递给void*(*start_routine)(void *)的参数。
pthread_exit
函数原型:void pthread_exit(void *retval);
函数功能:终止调用它的线程并返回一个指向某个对象的指针。
参数说明:要返回的对象的指针,返回的值需要通过pthread_join才能得到。
注意!绝对不能返回局部变量的指针,因为线程结束后,局部变量就不存在了。
pthread_join
函数原型:int pthread_join(pthread_t thread, void **thread_return);
函数功能:用于等待收集线程的信息。
函数返回:调用成功返回0,调用失败返回错误代码。
参数说明:
第一个参数pthread_tthread,指定将要等待的线程,线程通过pthread_create返回的标识符来指定。
第二个参数void**thread_return,它本身是一个指针,指向另一个指针,而后者指向线程的返回值。
代码实践:
- #include <pthread.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- void *pthread1(void *arg);
- void *pthread2(void *arg);
- int main()
- {
- pthread_t thread_id1,thread_id2;
- void *thread_result1, *thread_result2;
- int res;
-
- res = pthread_create(&thread_id1,NULL,pthread1,NULL);
- if(res){
- perror("pthread1 is not created ...\n");
- exit(EXIT_FAILURE);
- }
- res = pthread_create(&thread_id2,NULL,pthread2,NULL);
- if(res){
- perror("pthread2 is not created ...\n");
- exit(EXIT_FAILURE);
- }
- res = pthread_join(thread_id1,&thread_result1);
- if(res){
- perror("pthread1 join failed ...\n");
- exit(EXIT_FAILURE);
- }
- res = pthread_join(thread_id2,&thread_result2);
- if(res){
- perror("pthread2 join failed ...\n");
- exit(EXIT_FAILURE);
- }
-
- printf("the pthread1 return %s\n",(char *)thread_result1);
- printf("the pthread2 return %s\n",(char *)thread_result2);
- return 0;
- }
- void *pthread1(void *arg)
- {
- int i;
- for(i=0;i<10;i++){
- printf("hello this is pthread1 --> %d\n",i);
- sleep(1);
- }
- pthread_exit("pthread1 finished ...\n");
- }
- void *pthread2(void *arg)
- {
- int i;
- for(i=0;i<10;i++){
- printf("hello this is pthread2 --> %d\n",i);
- sleep(1);
- }
- pthread_exit("pthread2 finished ...\n");
- }
复制代码
运行结果:
- [yuanlai@fedora pthread]$ ls
- pthread0_arm pthread0.c
- [yuanlai@fedora pthread]$ gcc -D_REENTRANT pthread0.c -o pthread0 -lpthread
- [yuanlai@fedora pthread]$ ls
- pthread0 pthread0_arm pthread0.c
- [yuanlai@fedora pthread]$ ./pthread0
- hello this is pthread1 --> 0
- hello this is pthread2 --> 0
- hello this is pthread2 --> 1
- hello this is pthread1 --> 1
- hello this is pthread2 --> 2
- hello this is pthread1 --> 2
- hello this is pthread2 --> 3
- hello this is pthread1 --> 3
- hello this is pthread2 --> 4
- hello this is pthread1 --> 4
- hello this is pthread2 --> 5
- hello this is pthread1 --> 5
- hello this is pthread2 --> 6
- hello this is pthread1 --> 6
- hello this is pthread2 --> 7
- hello this is pthread1 --> 7
- hello this is pthread2 --> 8
- hello this is pthread1 --> 8
- hello this is pthread2 --> 9
- hello this is pthread1 --> 9
- the pthread1 return pthread1 finished ...
- the pthread2 return pthread2 finished ...
- [yuanlai@fedora pthread]$
复制代码 程序正常运行,会有三个线程,一个主线程,两个子线程,由于没有任何的同步机制,两个子线程的输出结果并没有什么规律。
论坛ID:yuanlai2010
发表时间:2014-09-11