pthread_craete()出來的線程,joinable或detached兩者必占之一。
如果是jionale的線程,那麼必須使用pthread_join()等待線程結束,否則線程所占用的資源不會得到釋放,會造成資源洩露。如果想創建一個線程,但又不想使用pthread_join()等待該線程結束,那麼可以創建一個detached的線程。detached狀態的線程,在結束的時候,會自動釋放該線程所占用的資源。
detached不需要,也不能使用pthread_join()來等待線程結束。
另外,一個jionale線程,只能有一個pthread_jion()來等待結束,如果有多個,則只有第一個執行到的有效,其他的都會直接返回,具體錯誤信息由pthread_join()函數的返回值返回。
上代碼,主要是joinable及detached狀態線程的創建,同一線程多個pthread_join(),pthread_join()一個detached線程:
[cpp]
#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;
}
[cpp]
運行結果:
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