与线程有关的函数构成了一个完整的系列,绝大多数函数的名字都是以“pthread_”打头,要使用这些函数库,要通过引入头文<pthread.h>,而且链接这些线程函数库时要使用编译器命令的“-lpthread”选项[Ubuntu系列系统需要添加的是”-pthread”选项而不是”-lpthread”,如Ubuntu 14.04版本,深度Ubuntu等]
pthread_create
创建一个新的线程
int pthread_create(pthread_t *restrict thread,
const pthread_attr_t *restrict attr,
void *(*start_routine)(void*), void *restrict arg);参数:
thread:线程ID
attr:设置线程的属性,attr为NULL表示使用默认属性
start_routine:是个函数地址,线程启动后要执行的函数
arg:传给线程启动函数的参数
返回值:成功返回0;失败返回错误码
附-错误检查
UNIX传统的函数:成功返回0,失败返回-1,并且对设置全局变量errno以指定错误类型。然而pthreads函数出错时不会设置全局变量errno(而其他的大部分POSIX函数会设置errno)。而是将错误代码通过返回值返回;
pthreads同样也提供了线程内的errno变量,以支持其它使用errno的代码。对于pthreads函数的错误,建议通过返回值进行判定,因为读取返回值要比读取线程内的errno变量的开销更小!
//实践
#include <iostream>
#include <errno.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
void *thread_routine(void *args)
{
for (int i = 0; i < 20; ++i)
{
printf("A");
fflush(stdout);
usleep(20);
}
return 0;
}
int main()
{
pthread_t tid;
int ret = 0;
if ((ret = pthread_create(&tid,NULL, thread_routine,NULL),NULL) != 0)
{
fprintf(stderr,"%s\n",strerror(ret));
exit(-1);
}
for (int i = 0; i < 20; ++i)
{
printf("B");
fflush(stdout);
usleep(20);
}
cout << endl;
pthread_join(tid,NULL); //该函数下面会遇到:等待线程结束
}运行结果(可以发现线程是交替运行的,并且运行情况不一):
pthread_exit
线程终止
void pthread_exit(void *value_ptr);
参数:
value_ptr:指向该线程的返回值;注意:value_ptr不能指向一个局部变量。
pthread_join
等待线程结束
int pthread_join(pthread_t thread, void **value_ptr);
参数:
thread:线程ID
value_ptr:它指向一个指针,后者指向线程的返回值(用户获取线程的返回值)
返回值:成功返回0;失败返回错误码
//实践
void *threadFunction(void *args)
{
cout << "Start Thread..." << endl;
cout << "End Thread..." << endl;
pthread_exit(NULL);
}
int main()
{
pthread_t thread;
//启动创建并启动线程
pthread_create(&thread,NULL,threadFunction,NULL);
cout << "Main Running..." << endl;
cout << "Main Ending..." << endl;
//等待线程结束
pthread_join(thread,NULL);
return 0;
}pthread_self
返回线程ID
pthread_t pthread_self(void);
DESCRIPTION
The pthread_self() function shall return the thread ID of the calling thread.//实践1:
void *thread_routine(void *args)
{
cout << pthread_self() << " START..." << endl;
for (int i = 0; i < 20; ++i)
{
printf("A");
fflush(stdout);
usleep(20);
}
sleep(3);
cout << pthread_self() << " END..." << endl;
pthread_exit(const_cast<char *>("thread_routine exit"));
//return (void *)"EDF";
}
int main()
{
pthread_t tid;
int ret = 0;
if ((ret = pthread_create(&tid,NULL, thread_routine,NULL),NULL) != 0)
{
fprintf(stderr,"pthread_create: %s\n",strerror(ret));
exit(EXIT_FAILURE);
}
for (int i = 0; i < 20; ++i)
{
printf("B");
fflush(stdout);
usleep(20);
}
cout << endl;
void *threadValue;
if ((ret = pthread_join(tid,&threadValue)) != 0)
{
fprintf(stderr, "pthread_join: %s\n",strerror(ret));
exit(EXIT_FAILURE);
}
cout << "return message: " << static_cast<char *>(threadValue) << endl;
}//实践2:主控线程与子线程传递数据
typedef struct _Student
{
char name[20];
unsigned int age;
} Student;
void *threadFunction(void *args)
{
cout << "In Thread: " << pthread_self() << endl;
Student tmp = *(Student *)(args);
cout << "Name: " << tmp.name << endl;
cout << "Age: " << tmp.age << endl;
pthread_exit(NULL);
}
int main()
{
Student student = {"xiaofang",22};
pthread_t thread;
//启动创建并启动线程
pthread_create(&thread,NULL,threadFunction,&student);
//等待线程结束
pthread_join(thread,NULL);
return 0;
}pthread_cancel
取消一个执行中的线程
int pthread_cancel(pthread_t thread);
返回值:成功返回0;失败返回错误码;
pthread_detach
将一个线程分离-如果在新创建的线程结束时主线程没有结束同时也没有调用pthread_join,则会产生僵线程,次问题可以通过设置线程为分离的(detach)来解决;
int pthread_detach(pthread_t thread);
返回值:成功返回0;失败返回错误码;
总结:进程 VS. 线程
进程(pid_t) | 线程(pthread_t) |
Fork | Pthread_create |
Waitpit | Pthread_join/Pthread_detach |
Kill | Pthread_cancel |
Pid | Pthead_self |
Exit/return | Pthread_exit/return |
原文地址:http://blog.csdn.net/zjf280441589/article/details/42211495