1、pthread_create以及pthread_self函数
1 /************************************************************************* 2 > File Name: pthread1.c 3 > Summary: 两个函数的使用:pthread_create() 以及函数 pthread_self() 4 > Author: xuelisheng 5 > Created Time: 2018年12月13日 6 ************************************************************************/ 7 8 #include<stdio.h> 9 #include<stdlib.h> 10 #include<pthread.h> 11 12 void *callBack() 13 { 14 // pthread_self():用来获得线程id。返回值为线程id,没有参数。 15 printf("pthread_self return value = %lu", pthread_self()); 16 return NULL; 17 } 18 19 int main() 20 { 21 pthread_t pid; 22 /* 23 pthread_create():成功返回值0,失败返回一个错误号(非0的值)。 24 参数1:pthread_t tid; 传出参数,指向线程标识符的指针。 &tid 25 参数2:属性 NULL 26 参数3:回调函数的函数指针。 27 参数4:回调函数的参数列表。没有的话传NULL 28 */ 29 int ret = pthread_create(&pid,NULL,callBack,NULL); 30 if(ret != 0) 31 { 32 printf("pthread_create fail "); 33 exit(-1); 34 } 35 //阻塞主线程一会 36 sleep(1); 37 return 0; 38 }
运行结果:
pthread_self return value = 140083744417536
2、循环创建多个子线程
第一种情况:
1 /************************************************************************* 2 > File Name: pthread2.c 3 > Summary: pthread_create() 循环创建多个线程 4 > Author: xuelisheng 5 > Created Time: 2018年12月13日 6 ************************************************************************/ 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <unistd.h> 12 #include <errno.h> 13 #include <pthread.h> 14 15 void *callBack(void *arg) 16 { 17 int i = (int)arg; 18 sleep(i); 19 // pthread_self():用来获得线程id。返回值为线程id,没有参数。 20 printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu ", i+1, getpid(), pthread_self()); 21 return NULL; 22 } 23 24 int main() 25 { 26 pthread_t pid; 27 /* 28 pthread_create():成功返回值0,失败返回一个错误号(非0的值)。 29 参数1:pthread_t tid; 传出参数,指向线程标识符的指针。 &tid 30 参数2:属性 null 31 参数3:回调函数的函数指针。 32 参数4:回调函数的参数列表。没有的话传NULL 33 */ 34 int i; 35 for(i = 0; i<5; i++) 36 { 37 int ret = pthread_create(&pid,NULL,callBack, (void *)i); 38 if(ret != 0) 39 { 40 printf("pthread_create fail "); 41 exit(-1); 42 } 43 } 44 45 //阻塞主线程一会 46 sleep(i); 47 printf("i am main thread,getpid() = %d,pthread_self return value = %lu ", getpid(), pthread_self()); 48 return 0; 49 }
运行结果:
1 i am 1 th thread,getpid() = 10595,pthread_self return value = 140194122020608 2 i am 2 th thread,getpid() = 10595,pthread_self return value = 140194113627904 3 i am 3 th thread,getpid() = 10595,pthread_self return value = 140194105235200 4 i am 4 th thread,getpid() = 10595,pthread_self return value = 140194096842496 5 i am 5 th thread,getpid() = 10595,pthread_self return value = 140194088449792 6 i am main thread,getpid() = 10595,pthread_self return value = 140194130355968
第二种情况:
1 /************************************************************************* 2 > File Name: pthread3.c 3 > Summary: pthread_create() 循环创建多个线程(第二种情况) 4 > Author: xuelisheng 5 > Created Time: 2018年12月13日 6 ************************************************************************/ 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <unistd.h> 12 #include <errno.h> 13 #include <pthread.h> 14 15 //void *callBack(void *arg) 16 //{ 17 // int i = (int)arg; 18 void *callBack(void *arg) 19 { 20 int i = *((int *)arg); 21 sleep(i); 22 // pthread_self():用来获得线程id。返回值为线程id,没有参数。 23 printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu ", i+1, getpid(), pthread_self()); 24 return NULL; 25 } 26 27 int main() 28 { 29 pthread_t pid; 30 /* 31 pthread_create():成功返回值0,失败返回一个错误号(非0的值)。 32 参数1:pthread_t tid; 传出参数,指向线程标识符的指针。 &tid 33 参数2:属性 null 34 参数3:回调函数的函数指针。 35 参数4:回调函数的参数列表。没有的话传NULL 36 */ 37 int i; 38 for(i = 0; i<5; i++) 39 { 40 //int ret = pthread_create(&pid,NULL,callBack, (void *)i); 41 int ret = pthread_create(&pid,NULL,callBack, (void *)&i); //注意这里如果取地址,主线程的i不断变化,所以取到的i值出现混乱 42 if(ret != 0) 43 { 44 printf("pthread_create fail "); 45 exit(-1); 46 } 47 } 48 49 //阻塞主线程一会 50 sleep(i); 51 printf("i am main thread,getpid() = %d,pthread_self return value = %lu ", getpid(), pthread_self()); 52 return 0; 53 }
运行结果:
1 i am 3 th thread,getpid() = 11433,pthread_self return value = 140484748015360 2 i am 4 th thread,getpid() = 11433,pthread_self return value = 140484739622656 3 i am 4 th thread,getpid() = 11433,pthread_self return value = 140484731229952 4 i am 5 th thread,getpid() = 11433,pthread_self return value = 140484722837248 5 i am main thread,getpid() = 11433,pthread_self return value = 140484756350720
3、线程间全局变量共享
1 /************************************************************************* 2 > File Name: pthread4.c 3 > Summary: 线程间全局变量共享 验证 4 > Author: xuelisheng 5 > Created Time: 2018年12月13日 6 ************************************************************************/ 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <unistd.h> 12 #include <errno.h> 13 #include <pthread.h> 14 15 // 定义全局变量 16 int var = 100; 17 void *callBack() 18 { 19 var = 200; 20 printf("child thread running now var = %d ", var); 21 return NULL; 22 } 23 24 int main() 25 { 26 printf("before child thread create var = %d ", var); 27 pthread_t pid; 28 /* 29 pthread_create():成功返回值0,失败返回一个错误号(非0的值)。 30 参数1:pthread_t tid; 传出参数,指向线程标识符的指针。 &tid 31 参数2:属性 null 32 参数3:回调函数的函数指针。 33 参数4:回调函数的参数列表。没有的话传NULL 34 */ 35 int ret = pthread_create(&pid,NULL,callBack, NULL); 36 if(ret != 0) 37 { 38 printf("pthread_create fail "); 39 exit(-1); 40 } 41 //阻塞主线程一会 42 sleep(1); 43 printf("after child thread over now var = %d ", var); 44 return 0; 45 }
运行结果:
1 before child thread create var = 100 2 child thread running now var = 200 3 after child thread over now var = 200
4、函数pthread_exit()
情形一:
1 /************************************************************************* 2 > File Name: pthread5.c 3 > Summary: pthread_exit函数之 使用exit函数退出线程 4 > Author: xuelisheng 5 > Created Time: 2018年12月13日 6 ************************************************************************/ 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <unistd.h> 12 #include <errno.h> 13 #include <pthread.h> 14 15 void *callBack(void *arg) 16 { 17 int i = (int)arg; 18 sleep(i); 19 if(i == 2){ 20 exit(0); 21 } 22 23 // pthread_self():用来获得线程id。返回值为线程id,没有参数。 24 printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu ", i+1, getpid(), pthread_self()); 25 return NULL; 26 } 27 28 int main() 29 { 30 pthread_t pid; 31 /* 32 pthread_create():成功返回值0,失败返回一个错误号(非0的值)。 33 参数1:pthread_t tid; 传出参数,指向线程标识符的指针。 &tid 34 参数2:属性 null 35 参数3:回调函数的函数指针。 36 参数4:回调函数的参数列表。没有的话传NULL 37 */ 38 int i; 39 for(i = 0; i<5; i++) 40 { 41 int ret = pthread_create(&pid,NULL,callBack, (void *)i); 42 if(ret != 0) 43 { 44 printf("pthread_create fail "); 45 exit(-1); 46 } 47 } 48 49 //阻塞主线程一会 50 sleep(i); 51 printf("i am main thread,getpid() = %d,pthread_self return value = %lu ", getpid(), pthread_self()); 52 return 0; 53 }
运行结果:
i am 1 th thread,getpid() = 14603,pthread_self return value = 139796530956032 i am 2 th thread,getpid() = 14603,pthread_self return value = 139796522563328
使用exit函数退出线程:exit()
是进程退出,如果在线程函数中调用exit,那改线程的进程也就挂了,会导致该线程所在进程的其他线程也挂掉,比较严重。
情形2-1:使用return 退出线程
1 /************************************************************************* 2 > File Name: pthread6.c 3 > Summary: pthread_exit函数之 使用return 退出线程 4 > Author: xuelisheng 5 > Created Time: 2018年12月13日 6 ************************************************************************/ 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <unistd.h> 12 #include <errno.h> 13 #include <pthread.h> 14 15 void *callBack(void *arg) 16 { 17 int i = (int)arg; 18 sleep(i); 19 if(i == 2){ 20 return NULL; 21 } 22 23 // pthread_self():用来获得线程id。返回值为线程id,没有参数。 24 printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu ", i+1, getpid(), pthread_self()); 25 return NULL; 26 } 27 28 int main() 29 { 30 pthread_t pid; 31 /* 32 pthread_create():成功返回值0,失败返回一个错误号(非0的值)。 33 参数1:pthread_t tid; 传出参数,指向线程标识符的指针。 &tid 34 参数2:属性 null 35 参数3:回调函数的函数指针。 36 参数4:回调函数的参数列表。没有的话传NULL 37 */ 38 int i; 39 for(i = 0; i<5; i++) 40 { 41 int ret = pthread_create(&pid,NULL,callBack, (void *)i); 42 if(ret != 0) 43 { 44 printf("pthread_create fail "); 45 exit(-1); 46 } 47 } 48 49 //阻塞主线程一会 50 sleep(i); 51 printf("i am main thread,getpid() = %d,pthread_self return value = %lu ", getpid(), pthread_self()); 52 return 0; 53 }
运行结果:(正常)
1 i am 1 th thread,getpid() = 15009,pthread_self return value = 140509750220544 2 i am 2 th thread,getpid() = 15009,pthread_self return value = 140509741827840 3 i am 4 th thread,getpid() = 15009,pthread_self return value = 140509725042432 4 i am 5 th thread,getpid() = 15009,pthread_self return value = 140509716649728 5 i am main thread,getpid() = 15009,pthread_self return value = 140509758555904
情形2-2:使用return 退出线程(嵌套)
1 /************************************************************************* 2 > File Name: pthread7.c 3 > Summary: pthread_exit函数之 使用return 退出线程(嵌套) 4 > Author: xuelisheng 5 > Created Time: 2018年12月13日 6 ************************************************************************/ 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <unistd.h> 12 #include <errno.h> 13 #include <pthread.h> 14 15 void *fun(){ 16 return NULL; 17 } 18 19 void *callBack(void *arg) 20 { 21 int i = (int)arg; 22 sleep(i); 23 if(i == 2){ 24 fun(); 25 } 26 27 // pthread_self():用来获得线程id。返回值为线程id,没有参数。 28 printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu ", i+1, getpid(), pthread_self()); 29 return NULL; 30 } 31 32 int main() 33 { 34 pthread_t pid; 35 /* 36 pthread_create():成功返回值0,失败返回一个错误号(非0的值)。 37 参数1:pthread_t tid; 传出参数,指向线程标识符的指针。 &tid 38 参数2:属性 null 39 参数3:回调函数的函数指针。 40 参数4:回调函数的参数列表。没有的话传NULL 41 */ 42 int i; 43 for(i = 0; i<5; i++) 44 { 45 int ret = pthread_create(&pid,NULL,callBack, (void *)i); 46 if(ret != 0) 47 { 48 printf("pthread_create fail "); 49 exit(-1); 50 } 51 } 52 53 //阻塞主线程一会 54 sleep(i); 55 printf("i am main thread,getpid() = %d,pthread_self return value = %lu ", getpid(), pthread_self()); 56 return 0; 57 }
运行结果:(不正常)
i am 1 th thread,getpid() = 15242,pthread_self return value = 140151373674240 i am 2 th thread,getpid() = 15242,pthread_self return value = 140151365281536 i am 3 th thread,getpid() = 15242,pthread_self return value = 140151356888832 i am 4 th thread,getpid() = 15242,pthread_self return value = 140151348496128 i am 5 th thread,getpid() = 15242,pthread_self return value = 140151340103424 i am main thread,getpid() = 15242,pthread_self return value = 140151382009600
结论:return
是函数返回,不一定是线程函数哦(情形2-2)! 只有线程函数(情形2-1)return,线程才会退出。
情形3-1:使用pthread_exit函数退出
1 /************************************************************************* 2 > File Name: pthread8.c 3 > Summary: pthread_exit函数 情形1 4 > Author: xuelisheng 5 > Created Time: 2018年12月13日 6 ************************************************************************/ 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <unistd.h> 12 #include <errno.h> 13 #include <pthread.h> 14 15 void *callBack(void *arg) 16 { 17 int i = (int)arg; 18 sleep(i); 19 if(i == 2){ 20 // 函数的作用是,终止调用它的线程并返回一个指向某个对象的指针。函数无返回值,参数为传出参数。 21 pthread_exit(NULL); 22 } 23 24 // pthread_self():用来获得线程id。返回值为线程id,没有参数。 25 printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu ", i+1, getpid(), pthread_self()); 26 return NULL; 27 } 28 29 int main() 30 { 31 pthread_t pid; 32 /* 33 pthread_create():成功返回值0,失败返回一个错误号(非0的值)。 34 参数1:pthread_t tid; 传出参数,指向线程标识符的指针。 &tid 35 参数2:属性 null 36 参数3:回调函数的函数指针。 37 参数4:回调函数的参数列表。没有的话传NULL 38 */ 39 int i; 40 for(i = 0; i<5; i++) 41 { 42 int ret = pthread_create(&pid,NULL,callBack, (void *)i); 43 if(ret != 0) 44 { 45 printf("pthread_create fail "); 46 exit(-1); 47 } 48 } 49 50 //阻塞主线程一会 51 sleep(i); 52 printf("i am main thread,getpid() = %d,pthread_self return value = %lu ", getpid(), pthread_self()); 53 return 0; 54 }
运行结果:(正常)
i am 1 th thread,getpid() = 15695,pthread_self return value = 139924312561408 i am 2 th thread,getpid() = 15695,pthread_self return value = 139924304168704 i am 4 th thread,getpid() = 15695,pthread_self return value = 139924287383296 i am 5 th thread,getpid() = 15695,pthread_self return value = 139924278990592 i am main thread,getpid() = 15695,pthread_self return value = 139924320896768
情形3-2:使用pthread_exit函数退出(嵌套)
1 /************************************************************************* 2 > File Name: pthread9.c 3 > Summary: pthread_exit函数 情形2 (嵌套) 4 > Author: xuelisheng 5 > Created Time: 2018年12月13日 6 ************************************************************************/ 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <unistd.h> 12 #include <errno.h> 13 #include <pthread.h> 14 15 void *fun() 16 { 17 pthread_exit(NULL); 18 } 19 20 void *callBack(void *arg) 21 { 22 int i = (int)arg; 23 sleep(i); 24 if(i == 2){ 25 // 函数的作用是,终止调用它的线程并返回一个指向某个对象的指针。函数无返回值,参数为传出参数。 26 //pthread_exit(NULL); 27 fun(); 28 } 29 30 // pthread_self():用来获得线程id。返回值为线程id,没有参数。 31 printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu ", i+1, getpid(), pthread_self()); 32 return NULL; 33 } 34 35 int main() 36 { 37 pthread_t pid; 38 /* 39 pthread_create():成功返回值0,失败返回一个错误号(非0的值)。 40 参数1:pthread_t tid; 传出参数,指向线程标识符的指针。 &tid 41 参数2:属性 null 42 参数3:回调函数的函数指针。 43 参数4:回调函数的参数列表。没有的话传NULL 44 */ 45 int i; 46 for(i = 0; i<5; i++) 47 { 48 int ret = pthread_create(&pid,NULL,callBack, (void *)i); 49 if(ret != 0) 50 { 51 printf("pthread_create fail "); 52 exit(-1); 53 } 54 } 55 56 //阻塞主线程一会 57 sleep(i); 58 printf("i am main thread,getpid() = %d,pthread_self return value = %lu ", getpid(), pthread_self()); 59 return 0; 60 }
运行结果:(正常)
i am 1 th thread,getpid() = 15902,pthread_self return value = 140551462266624 i am 2 th thread,getpid() = 15902,pthread_self return value = 140551453873920 i am 4 th thread,getpid() = 15902,pthread_self return value = 140551437088512 i am 5 th thread,getpid() = 15902,pthread_self return value = 140551428695808 i am main thread,getpid() = 15902,pthread_self return value = 140551470601984
pthread_exit()
用于线程退出,可以指定返回值,以便其他线程通过pthread_join()
函数获取该线程的返回值。
情形4:主函数中使用pthread_exit替代sleep:
1 /************************************************************************* 2 > File Name: pthread10.c 3 > Summary: pthread_create() 循环创建多个线程 主函数中使用pthread_exit替代sleep 4 > Author: xuelisheng 5 > Created Time: 2018年12月13日 6 ************************************************************************/ 7 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 #include <unistd.h> 12 #include <errno.h> 13 #include <pthread.h> 14 15 void *callBack(void *arg) 16 { 17 int i = (int)arg; 18 sleep(i); 19 // pthread_self():用来获得线程id。返回值为线程id,没有参数。 20 printf("i am %d th thread,getpid() = %d,pthread_self return value = %lu ", i+1, getpid(), pthread_self()); 21 return NULL; 22 } 23 24 int main() 25 { 26 pthread_t pid; 27 /* 28 pthread_create():成功返回值0,失败返回一个错误号(非0的值)。 29 参数1:pthread_t tid; 传出参数,指向线程标识符的指针。 &tid 30 参数2:属性 null 31 参数3:回调函数的函数指针。 32 参数4:回调函数的参数列表。没有的话传NULL 33 */ 34 int i; 35 for(i = 0; i<5; i++) 36 { 37 int ret = pthread_create(&pid,NULL,callBack, (void *)i); 38 if(ret != 0) 39 { 40 printf("pthread_create fail "); 41 exit(-1); 42 } 43 } 44 45 //阻塞主线程一会 46 //sleep(i); 47 printf("i am main thread,getpid() = %d,pthread_self return value = %lu ", getpid(), pthread_self()); 48 // 这里使用pthread_exit替换sleep() 49 pthread_exit(NULL); 50 return 0; // 主函数中使用return退出,相当于使用exit函数 51 }
运行结果:
i am main thread,getpid() = 16149,pthread_self return value = 140101106128640 i am 1 th thread,getpid() = 16149,pthread_self return value = 140101097793280 i am 2 th thread,getpid() = 16149,pthread_self return value = 140101089400576 i am 3 th thread,getpid() = 16149,pthread_self return value = 140101081007872 i am 4 th thread,getpid() = 16149,pthread_self return value = 140101072615168 i am 5 th thread,getpid() = 16149,pthread_self return value = 140101064222464