首页 > 代码库 > Linux多线程实践(2) --线程基本API
Linux多线程实践(2) --线程基本API
POSIX线程库
与线程有关的函数构成了一个完整的系列,绝大多数函数的名字都是以“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 |
Linux多线程实践(2) --线程基本API