pthread_craete()出来的线程,joinable或detached两者必占之一。
如果是jionale的线程,那么必须使用pthread_join()等待线程结束,否则线程所占用的资源不会得到释放,会造成资源泄露。如果想创建一个线程,但又不想使用pthread_join()等待该线程结束,那么可以创建一个detached的线程。detached状态的线程,在结束的时候,会自动释放该线程所占用的资源。另外,一个jionale线程,只能有一个pthread_jion()来等待结束,如果有多个,则只有第一个执行到的有效,其他的都会直接返回,具体错误信息由pthread_join()函数的返回值返回。
上代码,主要是joinable及detached状态线程的创建,同一线程多个pthread_join(),pthread_join()一个detached线程:
#include <pthread.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <string.h> // 线程ID pthread_t ntid_joinable; pthread_t ntid_detached; // 互斥对象 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; int count; void printids(const char *s) { pid_t pid; pthread_t tid; pid = getpid(); tid = pthread_self(); printf("%s pid %u tid %u (0x%x)\n", s, (unsigned int)pid, (unsigned int)tid, (unsigned int)tid); } // 线程函数 void *thr_joinablefn(void *arg) { printids("new thread thr_joinablefn begin\n"); // 加锁 pthread_mutex_lock(&mutex); printids("new thread thr_joinablefn:\n"); int i=0; for ( ; i<5; ++i) { printf("thr_joinablefn runing %d\n", count++); sleep(1); } // 释放互斥锁 pthread_mutex_unlock(&mutex); return ( (void*)555); } // 线程函数 void *thr_detachedfn(void *arg) { printids("new thread thr_detachedfn begin\n"); // 加锁 //pthread_mutex_lock(&mutex); int err; int **ret; err = pthread_join(ntid_joinable, (void**)ret); if ( err == 0 ) { printf("thr_joinablefn return in thr_detachedfn %d\n", *ret); } else { printf("can't pthread_join ntid_joinable thread in thr_detachedfn :%s\n", strerror(err)); } printids("new thread thr_detachedfn:\n"); int i=0; for ( ; i<10; ++i) { printf("thr_detachedfn runing %d\n", count++); sleep(1); } // 释放互斥锁 //pthread_mutex_unlock(&mutex); return ( (void*)666); } int main(void) { int err; count = 0; // 初始化互斥对象 pthread_mutex_init(&mutex, NULL); // 创建joinable线程 // pthread_craete第二个参数为NULL,则创建默认属性的线程,此时为PTHREAD_CREATE_JOINABLE err = pthread_create(&ntid_joinable, NULL, thr_joinablefn, NULL); if ( 0 != err ) { printf("can't create ntid_joinable thread:%s\n", strerror(err)); } // 创建detached线程 pthread_attr_t attr; pthread_attr_init(&attr); // 如果下句的 PTHREAD_CREATE_DETACHED 改为 PTHREAD_CREATE_JOINABLE // 则该线程与上面创建的线程一样 pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); err = pthread_create(&ntid_detached, &attr, thr_detachedfn, NULL); if ( 0 != err ) { printf("can't create thr_detachedfn thread:%s\n", strerror(err)); } pthread_attr_destroy (&attr); int **ret; err = pthread_join(ntid_joinable, (void**)ret); if ( err == 0 ) { printf("thr_joinablefn return %d\n", *ret); } else { printf("can't pthread_join ntid_joinable thread:%s\n", strerror(err)); } err = pthread_join(ntid_detached, (void**)ret); if ( err == 0 ) { printf("ntid_detached return %d\n", *ret); } else { printf("can't pthread_join ntid_detached thread:%s\n", strerror(err)); } pthread_mutex_destroy(&mutex); return 0; }
运行结果: new thread thr_joinablefn begin pid 2352 tid 4981312 (0x4c0240) new thread thr_detachedfn begin pid 2352 tid 5047072 (0x4d0320) new thread thr_joinablefn: pid 2352 tid 4981312 (0x4c0240) can't pthread_join ntid_joinable thread in thr_detachedfn :Invalid argument thr_joinablefn runing 0 new thread thr_detachedfn: pid 2352 tid 5047072 (0x4d0320) thr_detachedfn runing 1 thr_joinablefn runing 2 thr_detachedfn runing 3 thr_joinablefn runing 4 thr_detachedfn runing 5 thr_joinablefn runing 6 thr_detachedfn runing 7 thr_joinablefn runing 8 thr_detachedfn runing 9 thr_joinablefn return 555 thr_detachedfn runing 10 can't pthread_join ntid_detached thread:Invalid argument