Linux多线程实践(2) --线程基本API

转自http://blog.csdn.net/zjf280441589/article/details/42211495

POSIX线程库

与线程有关的函数构成了一个完整的系列,绝大多数函数的名字都是以“pthread_”打头,要使用这些函数库,要通过引入头文<pthread.h>,而且链接这些线程函数库时要使用编译器命令的“-lpthread”选项[Ubuntu系列系统需要添加的是”-pthread”选项而不是”-lpthread”,如Ubuntu 14.04版本,深度Ubuntu等]

 

pthread_create

创建一个新的线程

[cpp]  view plain copy
  1. int pthread_create(pthread_t *restrict thread,  
  2.        const pthread_attr_t *restrict attr,  
  3.        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变量的开销更小!

[cpp]  view plain copy
  1. //实践  
  2. #include <iostream>  
  3.   
  4. #include <errno.h>  
  5. #include <unistd.h>  
  6. #include <pthread.h>  
  7.   
  8. #include <string.h>  
  9. #include <stdio.h>  
  10. #include <stdlib.h>  
  11. using namespace std;  
  12.   
  13. void *thread_routine(void *args)  
  14. {  
  15.     for (int i = 0; i < 20; ++i)  
  16.     {  
  17.         printf("A");  
  18.         fflush(stdout);  
  19.         usleep(20);  
  20.     }  
  21.     return 0;  
  22. }  
  23.   
  24. int main()  
  25. {  
  26.     pthread_t tid;  
  27.     int ret = 0;  
  28.     if ((ret = pthread_create(&tid,NULL, thread_routine,NULL),NULL) != 0)  
  29.     {  
  30.         fprintf(stderr,"%s\n",strerror(ret));  
  31.         exit(-1);  
  32.     }  
  33.   
  34.     for (int i = 0; i < 20; ++i)  
  35.     {  
  36.         printf("B");  
  37.         fflush(stdout);  
  38.         usleep(20);  
  39.     }  
  40.   
  41.     cout << endl;  
  42.   
  43.     pthread_join(tid,NULL); //该函数下面会遇到:等待线程结束  
  44. }  


运行结果(可以发现线程是交替运行的,并且运行情况不一):

Linux多线程实践(2) --线程基本API_第1张图片

pthread_exit

线程终止

[cpp]  view plain copy
  1. void pthread_exit(void *value_ptr);  

参数:

value_ptr:指向该线程的返回值;注意:value_ptr不能指向一个局部变量

 

 

pthread_join

等待线程结束

[cpp]  view plain copy
  1. int pthread_join(pthread_t threadvoid **value_ptr);  

参数:

thread:线程ID

value_ptr:它指向一个指针,后者指向线程的返回值(用户获取线程的返回值)

返回值:成功返回0;失败返回错误码


[cpp]  view plain copy
  1. //实践  
  2. void *threadFunction(void *args)  
  3. {  
  4.     cout << "Start Thread..." << endl;  
  5.     cout << "End Thread..." << endl;  
  6.   
  7.     pthread_exit(NULL);  
  8. }  
  9.   
  10. int main()  
  11. {  
  12.     pthread_t thread;  
  13.     //启动创建并启动线程  
  14.     pthread_create(&thread,NULL,threadFunction,NULL);  
  15.   
  16.     cout << "Main Running..." << endl;  
  17.     cout << "Main Ending..." << endl;  
  18.   
  19.     //等待线程结束  
  20.     pthread_join(thread,NULL);  
  21.   
  22.     return 0;  
  23. }  


pthread_self

返回线程ID

[cpp]  view plain copy
  1. pthread_t pthread_self(void);  
  2. DESCRIPTION  
  3. <span style="white-space:pre">  </span>The pthread_self() function shall return the thread ID of the  calling thread.  

[cpp]  view plain copy
  1. //实践1:  
  2. void *thread_routine(void *args)  
  3. {  
  4.     cout << pthread_self() << " START..." << endl;  
  5.     for (int i = 0; i < 20; ++i)  
  6.     {  
  7.         printf("A");  
  8.         fflush(stdout);  
  9.         usleep(20);  
  10.     }  
  11.     sleep(3);  
  12.   
  13.     cout << pthread_self() << " END..." << endl;  
  14.     pthread_exit(const_cast<char *>("thread_routine exit"));  
  15.     //return (void *)"EDF";  
  16. }  
  17.   
  18. int main()  
  19. {  
  20.     pthread_t tid;  
  21.     int ret = 0;  
  22.     if ((ret = pthread_create(&tid,NULL, thread_routine,NULL),NULL) != 0)  
  23.     {  
  24.         fprintf(stderr,"pthread_create: %s\n",strerror(ret));  
  25.         exit(EXIT_FAILURE);  
  26.     }  
  27.   
  28.     for (int i = 0; i < 20; ++i)  
  29.     {  
  30.         printf("B");  
  31.         fflush(stdout);  
  32.         usleep(20);  
  33.     }  
  34.     cout << endl;  
  35.   
  36.     void *threadValue;  
  37.     if ((ret = pthread_join(tid,&threadValue)) != 0)  
  38.     {  
  39.         fprintf(stderr, "pthread_join: %s\n",strerror(ret));  
  40.         exit(EXIT_FAILURE);  
  41.     }  
  42.     cout << "return message: " << static_cast<char *>(threadValue) << endl;  
  43. }  
Linux多线程实践(2) --线程基本API_第2张图片

[cpp]  view plain copy
  1. //实践2:主控线程与子线程传递数据  
  2. typedef struct _Student  
  3. {  
  4.     char name[20];  
  5.     unsigned int age;  
  6. } Student;  
  7.   
  8. void *threadFunction(void *args)  
  9. {  
  10.     cout << "In Thread: " << pthread_self() << endl;  
  11.     Student tmp = *(Student *)(args);  
  12.     cout << "Name: " << tmp.name << endl;  
  13.     cout << "Age: " << tmp.age << endl;  
  14.   
  15.     pthread_exit(NULL);  
  16. }  
  17.   
  18. int main()  
  19. {  
  20.     Student student = {"xiaofang",22};  
  21.   
  22.     pthread_t thread;  
  23.     //启动创建并启动线程  
  24.     pthread_create(&thread,NULL,threadFunction,&student);  
  25.     //等待线程结束  
  26.     pthread_join(thread,NULL);  
  27.   
  28.     return 0;  
  29. }  

Linux多线程实践(2) --线程基本API_第3张图片


pthread_cancel

取消一个执行中的线程      

[cpp]  view plain copy
  1. int pthread_cancel(pthread_t thread);  

返回值:成功返回0;失败返回错误码;

 

pthread_detach

将一个线程分离-如果在新创建的线程结束时主线程没有结束同时也没有调用pthread_join,则会产生僵线程,次问题可以通过设置线程为分离的(detach)来解决;

[cpp]  view plain copy
  1. 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)