首页 > 技术知识 > 正文

Linux下线程编程

1.线程相关函数

 1.1创建线程pthread_create

  pthread_create是Unix操作系统(Unix、linux等)的创建线程的函数。

  注:编译时需要指定链接库 -lpthread

  函数原型: 复制#include int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg); 形参: thread — 指向线程标志符的指针类型为:pthread_t *   attr — 设置线程属性,默认填NULL。类型为:const pthread_attr_t *   void *(*start_routine) (void *) — 函数指针,现在运行函数的起始地址   arg — 运行函数的参数。不需要填NULL ,类型为:void * 返回值: 成功返回0;失败返回错误编号。   线程创建成功后,attr参数用于指定线程属性,新创建的线程函数形参只有一个void *形参,若需要传入的参数不止一个,则可以把需要传入的参数保存到一个结构体中,通过结构体传入。

  示例:

复制#include #include #include void *start_routine_func(void *arg) { while (1) { printf(“子线程运行中。。。\n”); sleep(1); } } int main() { int stat; pthread_t pth;//线程标志符 pthread_create(&pth,NULL,start_routine_func,NULL); while(1) { printf(“主线程运行中。。。\n”); sleep(1); } } [xsw@xsw 系统编程]$ gcc pthread.c -l pthread [xsw@xsw 系统编程]$ ./a.out 主线程运行中。。。 子线程运行中。。。 主线程运行中。。。 子线程运行中。。。 子线程运行中。。。 主线程运行中。。。  1.2 退出线程pthread_exit

  函数原型:

复制void pthread_exit(void *retval); 函数功能:   终止调用它的线程并通过形参返回一个指向某个对象的指针 形 参: void *retval — 线程需要返回的地址 返回值: 无   注:线程结束必须释放线程堆栈,也就是线程函数必须调用pthread_exit()结束,否则直到主进程函数退出才释放。

示例:

复制#include #include #include void *start_routine_func(void *arg) { int cnt=0; while (1) { printf(“子线程运行中cnt=%d。。。\n”,cnt); sleep(1); cnt++; if(cnt>=3)break; } pthread_exit(NULL);//退出线程,释放堆栈 } int main() { int stat; pthread_t pth;//线程标志符 /*创建子线线程*/ if(pthread_create(&pth,NULL,start_routine_func,NULL)!=0) { printf(“线程创建失败\n”); return 0; } printf(“子线程ID=%lu\n”,pth); /*等待线程退出*/ pthread_join(pth,NULL); printf(“线程退出成功\r\n”); return 0; } [xsw@xsw 系统编程]$ gcc pthread.c -lpthread [xsw@xsw 系统编程]$ ./a.out 子线程ID=3078433648 子线程运行中cnt=0。。。 子线程运行中cnt=1。。。 子线程运行中cnt=2。。。 线程退出成功  1.3 等待线程结束pthread_join 复制int pthread_join(pthread_t thread, void **retval); 函数功能:   以阻塞方式等待thread指定线程结束,当函数返回值,被等待线程的资源被回收。若线程已经结束,则立即返回。并且thread指定的线程必须是joinable(结合属性)属性。 形 参: thread — 线程标志符(线程ID)。线程唯一标志,类型为:pthread_t   retval — 用户定义的指针,用来存储被等待线程返回的地址 返回值: 成功返回0,失败返回错误编号。

示例:

复制#include #include #include void *start_routine_func(void *arg) { int cnt=0; while (1) { printf(“子线程运行中cnt=%d。。。\n”,cnt); sleep(1); cnt++; if(cnt>=3)break; } pthread_exit(NULL);//退出线程,释放堆栈 } int main() { int stat; pthread_t pth;//线程标志符 /*创建子线线程*/ if(pthread_create(&pth,NULL,start_routine_func,NULL)!=0) { printf(“线程创建失败\n”); return 0; } printf(“子线程ID=%lu\n”,pth); /*等待线程退出*/ pthread_join(pth,NULL); printf(“线程退出成功\r\n”); return 0; } [xsw@xsw 系统编程]$ gcc pthread.c -lpthread [xsw@xsw 系统编程]$ ./a.out 子线程ID=3078433648 子线程运行中cnt=0。。。 子线程运行中cnt=1。。。 子线程运行中cnt=2。。。 线程退出成功  1.4 获取当前线程标志符pthread_self

  函数原型:

复制pthread_t pthread_self(void); 函数功能:   获取线程自身ID。 形 参: 无 返回值: 返回当前线程标志符。pthread_t类型为unsigned long int,打印应%lu。

示例:

复制#include #include #include void *start_routine_func(void *arg) { printf(“子线程ID=%lu运行中。。。\n”,pthread_self()); pthread_exit(NULL);//退出线程,释放堆栈 } int main() { int stat; int i=0; pthread_t pth;//线程标志符 printf(“主线程ID=%lu\n”,pthread_self()); /*创建5个子线线程*/ for(i=0;i<5;i++) { if(pthread_create(&pth,NULL,start_routine_func,NULL)!=0) { printf(“线程创建失败\n”); return 0; } printf(“子线程ID=%lu\n”,pth); } /*等待线程退出*/ pthread_join(pth,NULL); printf(“线程退出成功\r\n”); return 0; } [xsw@xsw 系统编程]$ gcc pthread.c -lpthread [xsw@xsw 系统编程]$ ./a.out 主线程ID=3078706880 子线程ID=3078703984 子线程ID=3068214128 子线程ID=3057724272 子线程ID=3047234416 子线程ID=3036744560 子线程ID=3068214128运行中。。。 子线程ID=3078703984运行中。。。 子线程ID=3057724272运行中。。。 子线程ID=3047234416运行中。。。 子线程ID=3036744560运行中。。。 线程退出成功

 1.5 自动清理线程资源

  函数原型:

复制//注册清理函数 void pthread_cleanup_push(void (*routine)(void *),void *arg); //释放清理函数 void pthread_cleanup_pop(int execute); 函数功能:   线程清除处理函数,用于程序异常退出的时候做善后的资源清理。自动释放资源。   注:pthread_cleanup_push函数与pthread_cleanup_pop函数需要成对调用。 形 参:   void (*routine)(void *) — 处理程序函数入口   void *arg — 传递给处理函数形参   int execute — 执行的状态值,0 – 不调用清理函数;1 – 调用清理函数。 返回值: 无 导致调用清理函数条件:   1.调用pthread_exit()函数   2.Pthread_claenup_pop的形参为1   注:return不会导致清理函数调用。

示例:

复制#include #include #include /*线程清理函数*/ void routine_Clinen(void *arg) { printf(“arg=%d\n”,*(int *)arg); free(arg); printf(“释放空间完成\n”); } /*子线程函数*/ void *start_routine_func (void *arg) { printf(“arg=%s,线程运行中…\n”,arg); char *p=malloc(4); *p=100; //注册线程清理函数 pthread_cleanup_push(routine_Clinen,p); pthread_exit(“子线程返回数据测试!”);//释放线程堆栈 // return 0;//return终止不会触发线程清理函数 //调用线程清理函数 pthread_cleanup_pop(1); } int main() { /*1.创建线程*/ char buff[]=”线程传入参数测试”; pthread_t thread; if(pthread_create(&thread,NULL,start_routine_func,buff)!=0) { printf(“线程创建失败\n”); return 0; } printf(“线程ID=%lu\n”,pthread_self()); char *p; pthread_join(thread,(void **)&p);//等待线程退出 printf(“子线程返回数据:%s\n”,p); printf(“主线程退出\n”); return 0; } [xsw@xsw 系统编程]$ gcc pthread.c -lpthread [xsw@xsw 系统编程]$ ./a.out arg=线程传入参数测试,线程运行中… 线程ID=3078866624 arg=100 释放空间完成 子线程返回数据:子线程返回数据测试! 主线程退出

审核编辑:汤梓红

猜你喜欢