Linux 线程Pthread(一)创建、终止、获取TID 女爷i 2022-06-14 11:46 277阅读 0赞 多线程一直接触,这次系统学习一蛤。 多线程目的是在单进程环境下执行多个任务。一个进程中的所有线程都可以访问该进程的组成部件,如文件描述符和内存。 单个资源在多个用户间共享,就必须处理一致性问题。 同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符和信号处理等等。 但同一进程中的多个线程有各自的调用栈(call stack),自己的寄存器环境(register context),自己的线程本地存储(thread-local storage)。 通过`__thread`关键字是GCC内置的线程局部存储设施,存储效率堪比全局变量,它保证该变量在每个线程中都有独立的实体,互不干扰 ## 1.线程标识 ## 每个线程有一个线程ID,并且这个ID只有在它所属的进程上下文中才有意义。 #include <pthread.h> pthread_t pthread_self(void);//获取当前线程的线程ID #include <pthread.h> int pthread_equal(pthread_t tid1,pthread_t tid2); //相等返回非0 //否则返回0 `pid_t`用来标志进程,是一个非负整数,而`pthread_t`则有可能是一个结构体(取决于实现)。 因此,在调用`pthread_equal`的时候,参数必须严格是`pthread_t`类型的变量,否则将会出现未定义的行为: > The pthread\_equal() function shall return a non-zero value if t1 and t2 are equal; otherwise, zero shall be returned. > ***If either t1 or t2 are not valid thread IDs, the behavior is undefined.*** ## 2.创建线程 ## #include <pthread.h> int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg); `pthread_t * thread`指向线程创建成功时线程id所在的内存单元 `pthread_attr_t * attr`创建时属性 `start_routine`即run in thread回调,这是一个函数指针,指向函数返回`void*` 参数是`void*` `void *arg`即run in thread回调中的参数 ## 3.线程终止 ## 如果进程中的任意线程调用了`exit`、`_Exit`、`_exit`函数,那么整个进程就会终止。 如果终止进程,则发送到线程的信号就会终止整个进程。 通过在线程中调用`exit`系列函数发现,确实主进程也随着退出,那么如何优雅地退出? > 1.直接返回 return > 2.被其他线程取消 > 3.线程自己调用pthread\_exit 而通过`pthread_join`则可以知道`return`或者`pthread_exit`的状态码 #include <pthread.h> void pthread_exit(void *retval); #include <pthread.h> int pthread_join(pthread_t thread, void **retval); 另外,在APUE中提到一个很重要的点,使用`pthread_exit`返回的变量不能是栈上变量, 我们知道每个线程有自己的栈,当某一个线程`pthread_exit`返回后,栈空间可能被另外的线程所覆盖 为了解决这个问题,我们可以使用全局变量和malloc函数分配的堆变量 下面这个代码测试了上述所有函数,详见[github][] //thread_exit.c void *thread1(void *arg) { pthread_t *tid1=(pthread_t*)(arg); int ret = pthread_equal(*tid1,pthread_self()); printf("in thread1 tid = %lu, ret is %d\r\n",(unsigned long)pthread_self(),ret); return ((void*)2); } void *thread2(void *arg) { pthread_t *tid1=(pthread_t*)(arg); int *a= (int *)malloc(sizeof(int)); printf("in thread2 pointer %p\r\n",a); *a=5; int ret = pthread_equal(*tid1,pthread_self()); printf("in thread2 tid = %lu,ret is %d\r\n",(unsigned long)pthread_self(),ret); pthread_exit((void*)a); } int main(void ) { pthread_t tid1; pthread_t tid2; int ret; ret = pthread_create(&tid1,NULL,thread1,&tid1); assert(ret==0); ret = pthread_create(&tid2,NULL,thread2,&tid1);//test assert(ret==0); printf("main thread: %lu\r\n",(unsigned long)pthread_self()); void * status; pthread_join(tid1,&status); printf("thread %lu exit status is %ld\r\n",(unsigned long)tid1,(long)status); int *fuck; pthread_join(tid2,(void*)&fuck); printf("======%d\r\n",*fuck); printf("in main pointer %p\r\n",fuck); free(fuck);//malloc in thread //printf("thread %lu exit status is %d\r\n",(unsigned long)tid2,*(int *)status); printf("main thread exit\r\n"); return 0; } [github]: https://github.com/NearXdu/APUE
还没有评论,来说两句吧...