POSIX thread(pthread) (一)

来源:互联网 发布:ping命令是哪个端口 编辑:程序博客网 时间:2024/06/05 04:51

原文地址:http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html 

介绍:

pthread是基于C/C++的基本线程库。 pthread可以创建一个新的工作流,在多处理器或者多核上面尤其高效,因为他可以在多个处理器上并行执行。线程不需要初始化一块新的虚拟内存,所以线程比“forking”需要的开销少。他在多处理器上很高效,但在单处理器上也不差,因为它不会因为I/O或者系统调用而卡死(一个线程执行I/O操作,一个线程做其他的事情)。MPI或者PVM这写并行编程技术被运用在分布式计算环境当中,但线程只能在一台电脑上。所有的线程共享一个处理器的所有地址空间。使用pthread可以提高软件的运行速度。

基本概念:

线程的操作包括:创建,结束,同步(加入,阻塞),轮询,数据管理,交互处理

线程不会维护一个已创建的线程列表,也不知道是否有线程被创建

所有线程共享相同的地址空间

同一进程中的线程可以共享:

进程中的指令

大部分数据

打开的文件

信号和信号处理设备

当前工作目录

用户和组id

每一个线程都有唯一标示:

线程id

一些寄存器,栈指针

栈上的变量,返回地址

信号挡板

优先级

返回值:errno

pthread函数成功执行返回0

线程的创建和终止

例子:pthreadl.c

#include <stdio.h>#include <stdlib.h>#include <pthread.h>void *print_message_function( void *ptr );main(){     pthread_t thread1, thread2;     const char *message1 = "Thread 1";     const char *message2 = "Thread 2";     int  iret1, iret2;    /* Create independent threads each of which will execute function */     iret1 = pthread_create( &thread1, NULL, print_message_function, (void*) message1);     if(iret1)     {         fprintf(stderr,"Error - pthread_create() return code: %d\n",iret1);         exit(EXIT_FAILURE);     }     iret2 = pthread_create( &thread2, NULL, print_message_function, (void*) message2);     if(iret2)     {         fprintf(stderr,"Error - pthread_create() return code: %d\n",iret2);         exit(EXIT_FAILURE);     }     printf("pthread_create() for thread 1 returns: %d\n",iret1);     printf("pthread_create() for thread 2 returns: %d\n",iret2);     /* Wait till threads are complete before main continues. Unless we  */     /* wait we run the risk of executing an exit which will terminate   */     /* the process and all threads before the threads have completed.   */     pthread_join( thread1, NULL);     pthread_join( thread2, NULL);      exit(EXIT_SUCCESS);}void *print_message_function( void *ptr ){     char *message;     message = (char *) ptr;     printf("%s \n", message);}
编译:

C编译器:

cc -pthread pthread1.c (or cc -lpthread pthread1.c) 

C++编译器:

g++ -pthread pthread1.c (or g++ -lpthread pthread1.c)

现在的GNU编译器已经有"-pthread"这个选项了,老版本的编译器只能显示的指定"-lpthread"

运行:./a.out

结果:

Thread 1 

Thread 2 
pthread_create() for thread 1 returns: 0
pthread_create() for thread 2 returns: 0


(其实输出Thread1和Thread2这两个log的日志顺序并不是固定的,多试几次发现结果都不一样,这说明就算第一个线程先创建了,并不一定执行)

详细:

在这个例子当中不同的线程使用了相同的函数,但参数不同,当然函数也可以不一样。

调用pthread_exit()来终止线程的调用,并返回值。或者调用exit()方法来终止所有线程。


pthread_create可以创建一个新的线程

int pthread_create(pthread_t * thread,                        const pthread_attr_t * attr,                       void * (*start_routine)(void *),                        void *arg);

参数:

thread返回线程的id(unsigned long int,定义在bits/pthreadtypes.h)

attr如果是NULL,则使用默认的设置(pthread_attr_t定义在bits/pthreadtypes.h中),属性包括以下:

托管状态(默认PTHREAD_CREATE_JOINABLE,其它PTHREAD_CREATE_DETACHED)

        轮训策略(PTHREAD_INHERIT_SCHED,PTHREAD_EXPLICIT_SCHED,SCHED_OTHER)

轮询参数

继承属性(默认:PTHREAD_EXPLICIT_SCHED,继承父线程:PTHREAD_INHERIT_SCHED)

  类型(内核线程:PTHREAD_SCORE-SYSTEM 用户线程:PTHREAD_SCOPE_PROCESS)

guard size

栈地址(详情参照 unistd.h和bits/posix_opt.h _POSIX_THREAD_ATTR_STACKADDR)

栈大小(默认最小为PTHREAD_STACK_SIZE,参照pthread.h)

void *(*start_routine)线程执行函数,有个类型为void*的参数

*arg线程函数的参数,如果想传递多个变量可以传递structure的指针


pthread_join会等待另一个线程执行完毕

int pthread_join(pthread_t th,void **thread_return)

参数:

th 需等待执行完毕的线程,或者调用了pthread_exit(),或者被取消了

thread_return  假如不为NULL,th的返回值存储在里面


pthread_exit可以结束一个线程

void pthread_exit(void *retval)

参数:

retval执行pthread_exit()的返回值 


这个方法会杀死线程。pthread_exit()没有返回值。假如线程没有被杀死,那么可以使用pthread_join()来检查线程id和线程返回值。注意:*retval不能为线程中的局部变量,因为线程杀死过后变量就不存在了。

0 0