博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线程函数
阅读量:5930 次
发布时间:2019-06-19

本文共 4551 字,大约阅读时间需要 15 分钟。

线程函数

man pthreads了解线程相关内容。

线程函数成功返回0,失败返回错误码,不设置errno。POSIX.1-2001指出线程函数绝不会(never)返回EINTR(不会因EINTR而失败)。

  • 线程创建
#include
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,  void * (*start_routine)(void *), void * restrict arg);
 

attr一般为NULL,采用系统默认属性。

int pthread_attr_init(pthread_attr_t *attr);       int pthread_attr_destroy(pthread_attr_t *attr);

>>默认创建的线程是joinable的,可通过函数pthread_attr_setdetachstate()设置attr从而创建detached的线程。

>>可通过pthread_attr_setstacksize()设置attr从而创建指定栈大小的线程。pthread_attr_getstacksize()获取当线程栈大小。

成功返回0,失败返回错误号。

pthread_t无符号整型 typedef unsigned long int pthread_t

pthread库的函数都是通过返回值返回错误号,虽然每个线程都有一个errno,但并不使用它。因此不能调用perror打印错误信息,可先用strerror把返回值(错误码)转化为错误信息再打印。

注:线程函数参数和返回值都是void*,且函数返回的指针所指向的内存单元必须是全局的或者malloc分配的。

void * (*start_routine)(void *)
  • 线程终止

终止线程有三种方法:

1)从线程函数return。

2)调用pthread_cancel()终止同一进程中的另一个线程。

3)线程可调用pthread_exit()终止自己。

void pthread_exit(void *value_ptr);
 

无返回值,总是成功。

注:pthread_exit或者return返回的指针所指向的内存单元必须是全局的或者malloc分配的,不能在线程函数的栈上分配。

int pthread_cancel(pthread_t thread);
 

成功返回0,失败返回非零错误号。

被终止的线程的响应取决于可终止状态和类型(cancelability state and type).

注:如果任意一个线程调用exit或_exit,则整个进程的所有线程都终止。

  • 获取终止状态
int pthread_join(pthread_t thread, void **retval);
 

等待线程终止,并获取线程退出状态。该线程必须是joinable。调用该函数的线程将挂起等待,直到id为thread的线程终止。阻塞函数

函数调用时注意参数:定义为void *res; 调用pthread_join(&res);最终调用参数(char *)res。

retval:

1)如果thread线程通过return返回,thread线程函数返回值。

2)pthread_cancel()异常终止,则retval所指向的单元存放常量PTHREAD_CANCELED(-1)。

3)自己调用pthread_exit()终止,retval存放pthread_exit参数。

  • 分离线程
#include
int pthread_detach(pthread_t thread);
 

标记线程thread为分离状态。当一个分离状态的线程终止时,它的资源自动释放给系统,不需要其他线程join。

成功返回0,失败返回错误号。

注:让线程自己pthread_detach(线程函数内调用)不好,库函数不是原子的。

注:不能对一个已经处于detach状态的线程调用pthread_join.==>EINVAL.

注:不能对同一线程调用两次pthread_join或pthread_detach,或者一个线程已经调用pthread_detach就不能再调用pthread_join了。

注:线程创建时,都应该调用pthread_join()或pthread_detach(),以使系统资源释放。

示例:pthread_detach(pthread_self());

  • 获取线程id
pthread_t pthread_self(void);
 

函数总是成功,返回id。

  • 信号函数

线程信号用pthread_sigmask, pthread_kill。

线程读写用pread/pwrite.(文件偏移不改变)

 

manpage示例

#include 
#include
#include
#include
#include
#include
#include
#define handle_error_en(en, msg) \ do{ errno = en; perror(msg); exit(EXIT_FAILURE); } while(0)#define handle_error(msg) \ do { perror(msg); exit(EXIT_FAILURE); } while(0)struct thread_info{ pthread_t thread_id; int thread_num; char *argv_string;};static void * t1(void *arg){ struct thread_info *tinfo = arg; char *uargv, *p; printf("Thread %d: top of stack near %p; argv_string=%s\n", tinfo->thread_num, &p, tinfo->argv_string); uargv = strdup(tinfo->argv_string); if(uargv == NULL) printf("strdup error.\n"); for(p = uargv; *p != '\0'; p++) *p = toupper(*p); return uargv;}int main(int argc, char ** argv){ int s, tnum, opt, num_threads; struct thread_info *tinfo; pthread_attr_t attr; int stack_size; void *res; /* the "-s" option specifies a stack size for our threads */ stack_size = -1; while((opt = getopt(argc, argv, "s:")) != -1){ switch(opt){ case 's': stack_size = strtoul(optarg, NULL, 0); break; default: fprintf(stderr, "Usage: %s [-s stack-size] arg ...\n", argv[0]); exit(EXIT_FAILURE); } } num_threads = argc - optind; s = pthread_attr_init(&attr); if(s != 0) handle_error_en(s, "pthread_attr_init"); if(stack_size > 0){ s = pthread_attr_setstacksize(&attr, stack_size); if(s != 0) handle_error_en(s, "pthread_attr_setstacksize"); } tinfo = calloc(num_threads, sizeof(struct thread_info)); if(tinfo == NULL) handle_error("calloc"); for(tnum = 0; tnum < num_threads; tnum++){ tinfo[tnum].thread_num = tnum +1; tinfo[tnum].argv_string = argv[optind + tnum]; s = pthread_create(&tinfo[tnum].thread_id, &attr, &t1, &tinfo[tnum]); if(s != 0) handle_error_en(s, "pthread_create"); } s = pthread_attr_destroy(&attr); if(s != 0) handle_error_en(s, "pthread_attr_destroy"); for(tnum = 0; tnum < num_threads; tnum++){ s = pthread_join(tinfo[tnum].thread_id, &res); if(s != 0) handle_error_en(s, "pthread_join"); printf("Joined with thread %d; returned value was %s\n", tinfo[tnum].thread_num, (char*)res); free(res); } free(tinfo); exit(EXIT_SUCCESS);}

执行:

yuxi@ubuntu:~/test/pthread$ ./a.out yuxi@ubuntu:~/test/pthread$ ./a.out -s 0x100000 abc def CHAThread 3: top of stack near 0x7f7be5184f20; argv_string=CHAThread 2: top of stack near 0x7f7be5285f20; argv_string=defThread 1: top of stack near 0x7f7be5a74f20; argv_string=abcJoined with thread 1; returned value was ABCJoined with thread 2; returned value was DEFJoined with thread 3; returned value was CHA

 

转载地址:http://byutx.baihongyu.com/

你可能感兴趣的文章
JNI——访问数组
查看>>
C#开发和调用Web Service
查看>>
Android6.0机型上调用系统相机拍照返回的resultCode值始终等于0的问题
查看>>
全面理解Git
查看>>
JS敏感信息泄露:不容忽视的WEB漏洞
查看>>
让我们荡起双桨,Android 小船波浪动画
查看>>
ApacheCN 翻译活动进度公告 2019.2.18
查看>>
分布式memcached服务器代理magent安装配置(CentOS6.6)
查看>>
Create Volume 操作(Part III) - 每天5分钟玩转 OpenStack(52)
查看>>
物联网的广泛应用将扭转发展中经济体的局面 为全球发展带来新机遇
查看>>
Polar码引发舆论狂欢 5G标准远未定局
查看>>
IntersectionObserver + Custom Elements 实现图片懒加载(滚动加载)/点击重试
查看>>
KSImageNamed-Xcode-master
查看>>
memcache
查看>>
Struts2参数知识点
查看>>
tomcat 8.0虚拟机配置文档
查看>>
轻松实现基于Heartbeat的高可用web服务集群
查看>>
分析y一款APP
查看>>
我的 ubuntu14.04.3 LTS
查看>>
mac 安装office
查看>>