您的位置:首页 > 其它

POSIX thread(pthread) (一)

2015-01-22 16:23 357 查看
原文地址: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不能为线程中的局部变量,因为线程杀死过后变量就不存在了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: