日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當前位置:首頁 > 嵌入式 > 嵌入式教程
[導讀]這里要講的線程相關操作都是用戶空間中的線程的操作。在Linux中,一般pthread線程庫是一套通用的線程庫,是由POSIX提出的,因此具有很好的可移植性。

9.2 Linux線程編程9.2.1 線程基本編程

這里要講的線程相關操作都是用戶空間中的線程的操作。在Linux中,一般pthread線程庫是一套通用的線程庫,是由POSIX提出的,因此具有很好的可移植性。

(1)函數(shù)說明。

創(chuàng)建線程實際上就是確定調用該線程函數(shù)的入口點,這里通常使用的函數(shù)是pthread_create()。在線程創(chuàng)建以后,就開始運行相關的線程函數(shù),在該函數(shù)運行完之后,該線程也就退出了,這也是線程退出一種方法。另一種退出線程的方法是使用函數(shù)pthread_exit(),這是線程的主動行為。這里要注意的是,在使用線程函數(shù)時,不能隨意使用exit()退出函數(shù)進行出錯處理,由于exit()的作用是使調用進程終止,往往一個進程包含多個線程,因此,在使用exit()之后,該進程中的所有線程都終止了。因此,在線程中就可以使用pthread_exit()來代替進程中的exit()。

由于一個進程中的多個線程是共享數(shù)據(jù)段的,因此通常在線程退出之后,退出線程所占用的資源并不會隨著線程的終止而得到釋放。正如進程之間可以用wait()系統(tǒng)調用來同步終止并釋放資源一樣,線程之間也有類似機制,那就是pthread_join()函數(shù)。pthread_join()可以用于將當前線程掛起來等待線程的結束。這個函數(shù)是一個線程阻塞的函數(shù),調用它的函數(shù)將一直等待到被等待的線程結束為止,當函數(shù)返回時,被等待線程的資源就被收回。

前面已提到線程調用pthread_exit()函數(shù)主動終止自身線程。但是在很多線程應用中,經常會遇到在別的線程中要終止另一個線程的執(zhí)行的問題。此時調用pthread_cancel()函數(shù)實現(xiàn)這種功能,但在被取消的線程的內部需要調用pthread_setcancel()函數(shù)和pthread_setcanceltype()函數(shù)設置自己的取消狀態(tài),例如被取消的線程接收到另一個線程的取消請求之后,是接受還是忽略這個請求;如果接受,是立刻進行終止操作還是等待某個函數(shù)的調用等。

(2)函數(shù)格式。

表9.1列出了pthread_create()函數(shù)的語法要點。

表9.1 pthread_create()函數(shù)語法要點

所需頭文件

#include <pthread.h>

函數(shù)原型

int pthread_create ((pthread_t *thread, pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg))

函數(shù)傳入值

thread:線程標識符

attr:線程屬性設置(其具體設置參見9.2.3小節(jié)),通常取為NULL

start_routine:線程函數(shù)的起始地址,是一個以指向void的指針作為參數(shù)和返回值的函數(shù)指針

arg:傳遞給start_routine的參數(shù)

函數(shù)返回值

成功:0

出錯:返回錯誤碼

表9.2列出了pthread_exit()函數(shù)的語法要點。

表9.2 pthread_exit()函數(shù)語法要點

所需頭文件

#include <pthread.h>

函數(shù)原型

void pthread_exit(void *retval)

函數(shù)傳入值

retval:線程結束時的返回值,可由其他函數(shù)如pthread_join()來獲取

表9.3列出了pthread_join()函數(shù)的語法要點。

表9.3 pthread_join()函數(shù)語法要點

所需頭文件

#include <pthread.h>

函數(shù)原型

int pthread_join ((pthread_t th, void **thread_return))

函數(shù)傳入值

th:等待線程的標識符

thread_return:用戶定義的指針,用來存儲被等待線程結束時的返回值(不為NULL時)

函數(shù)返回值

成功:0

出錯:返回錯誤碼

表9.4列出了pthread_cancel()函數(shù)的語法要點。

表9.4 pthread_cancel()函數(shù)語法要點

所需頭文件

#include <pthread.h>

函數(shù)原型

int pthread_cancel((pthread_t th)

函數(shù)傳入值

th:要取消的線程的標識符

函數(shù)返回值

成功:0

出錯:返回錯誤碼

(3)函數(shù)使用。

以下實例中創(chuàng)建了3個線程,為了更好地描述線程之間的并行執(zhí)行,讓3個線程重用同一個執(zhí)行函數(shù)。每個線程都有5次循環(huán)(可以看成5個小任務),每次循環(huán)之間會隨機等待1~10s的時間,意義在于模擬每個任務的到達時間是隨機的,并沒有任何特定規(guī)律。

/* thread.c */

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#define THREAD_NUMBER 3 /*線程數(shù)*/

#define REPEAT_NUMBER 5 /*每個線程中的小任務數(shù)*/

#define DELAY_TIME_LEVELS 10.0 /*小任務之間的最大時間間隔*/

void *thrd_func(void *arg)

{ /* 線程函數(shù)例程 */

int thrd_num = (int)arg;

int delay_time = 0;

int count = 0;

printf("Thread %d is startingn", thrd_num);

for (count = 0; count < REPEAT_NUMBER; count++)

{

delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1;

sleep(delay_time);

printf("tThread %d: job %d delay = %dn",

thrd_num, count, delay_time);

}

printf("Thread %d finishedn", thrd_num);

pthread_exit(NULL);

}

int main(void)

{

pthread_t thread[THREAD_NUMBER];

int no = 0, res;

void * thrd_ret;

srand(time(NULL));

for (no = 0; no < THREAD_NUMBER; no++)

{

/* 創(chuàng)建多線程 */

res = pthread_create(&thread[no], NULL, thrd_func, (void*)no);

if (res != 0)

{

printf("Create thread %d failedn", no);

exit(res);

}

}

printf("Create treads successn Waiting for threads to finish...n");

for (no = 0; no < THREAD_NUMBER; no++)

{

/* 等待線程結束 */

res = pthread_join(thread[no], &thrd_ret);

if (!res)

{

printf("Thread %d joinedn", no);

}

else

{

printf("Thread %d join failedn", no);

}

}

return 0;

}

以下是程序運行結果??梢钥闯雒總€線程的運行和結束是獨立與并行的。

$ ./thread

Create treads success

Waiting for threads to finish...

Thread 0 is starting

Thread 1 is starting

Thread 2 is starting

Thread 1: job 0 delay = 6

Thread 2: job 0 delay = 6

Thread 0: job 0 delay = 9

Thread 1: job 1 delay = 6

Thread 2: job 1 delay = 8

Thread 0: job 1 delay = 8

Thread 2: job 2 delay = 3

Thread 0: job 2 delay = 3

Thread 2: job 3 delay = 3

Thread 2: job 4 delay = 1

Thread 2 finished

Thread 1: job 2 delay = 10

Thread 1: job 3 delay = 4

Thread 1: job 4 delay = 1

Thread 1 finished

Thread 0: job 3 delay = 9

Thread 0: job 4 delay = 2

Thread 0 finished

Thread 0 joined

Thread 1 joined

Thread 2 joined

9.2.2 線程之間的同步與互斥

由于線程共享進程的資源和地址空間,因此在對這些資源進行操作時,必須考慮到線程間資源訪問的同步與互斥問題。這里主要介紹POSIX中兩種線程同步機制,分別為互斥鎖和信號量。這兩個同步機制可以互相通過調用對方來實現(xiàn),但互斥鎖更適合用于同時可用的資源是惟一的情況;信號量更適合用于同時可用的資源為多個的情況。

1.互斥鎖線程控制

(1)函數(shù)說明。

互斥鎖是用一種簡單的加鎖方法來控制對共享資源的原子操作。這個互斥鎖只有兩種狀態(tài),也就是上鎖和解鎖,可以把互斥鎖看作某種意義上的全局變量。在同一時刻只能有一個線程掌握某個互斥鎖,擁有上鎖狀態(tài)的線程能夠對共享資源進行操作。若其他線程希望上鎖一個已經被上鎖的互斥鎖,則該線程就會掛起,直到上鎖的線程釋放掉互斥鎖為止??梢哉f,這把互斥鎖保證讓每個線程對共享資源按順序進行原子操作。

互斥鎖機制主要包括下面的基本函數(shù)。

n 互斥鎖初始化:pthread_mutex_init()

n 互斥鎖上鎖:pthread_mutex_lock()

n 互斥鎖判斷上鎖:pthread_mutex_trylock()

n 互斥鎖接鎖:pthread_mutex_unlock()

n 消除互斥鎖:pthread_mutex_destroy()

其中,互斥鎖可以分為快速互斥鎖、遞歸互斥鎖和檢錯互斥鎖。這3種鎖的區(qū)別主要在于其他未占有互斥鎖的線程在希望得到互斥鎖時是否需要阻塞等待。快速鎖是指調用線程會阻塞直至擁有互斥鎖的線程解鎖為止。遞歸互斥鎖能夠成功地返回,并且增加調用線程在互斥上加鎖的次數(shù),而檢錯互斥鎖則為快速互斥鎖的非阻塞版本,它會立即返回并返回一個錯誤信息。默認屬性為快速互斥鎖。

(2)函數(shù)格式。

表9.5列出了pthread_mutex_init()函數(shù)的語法要點。

表9.5 pthread_mutex_init()函數(shù)語法要點

所需頭文件

#include <pthread.h>

函數(shù)原型

int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)

函數(shù)傳入值

mutex:互斥鎖

Mutexattr

PTHREAD_MUTEX_INITIALIZER:創(chuàng)建快速互斥鎖

PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP:創(chuàng)建遞歸互斥鎖

PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP:創(chuàng)建檢錯互斥鎖

函數(shù)返回值

成功:0

出錯:返回錯誤碼

表9.6列出了pthread_mutex_lock()等函數(shù)的語法要點。

表9.6 pthread_mutex_lock()等函數(shù)語法要點

所需頭文件

#include <pthread.h>

函數(shù)原型

int pthread_mutex_lock(pthread_mutex_t *mutex,)
int pthread_mutex_trylock(pthread_mutex_t *mutex,)
int pthread_mutex_unlock(pthread_mutex_t *mutex,)
int pthread_mutex_destroy(pthread_mutex_t *mutex,)

函數(shù)傳入值

mutex:互斥鎖

函數(shù)返回值

成功:0

出錯:-1

(3)使用實例。

下面的實例是在9.2.1小節(jié)示例代碼的基礎上增加互斥鎖功能,實現(xiàn)原本獨立與無序的多個線程能夠按順序執(zhí)行。

/*thread_mutex.c*/

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#define THREAD_NUMBER 3 /* 線程數(shù) */

#define REPEAT_NUMBER 3 /* 每個線程的小任務數(shù) */

#define DELAY_TIME_LEVELS 10.0 /*小任務之間的最大時間間隔*/

pthread_mutex_t mutex;

void *thrd_func(void *arg)

{

int thrd_num = (int)arg;

int delay_time = 0, count = 0;

int res;

/* 互斥鎖上鎖 */

res = pthread_mutex_lock(&mutex);

if (res)

{

printf("Thread %d lock failedn", thrd_num);

pthread_exit(NULL);

}

printf("Thread %d is startingn", thrd_num);

for (count = 0; count < REPEAT_NUMBER; count++)

{

delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1;

sleep(delay_time);

printf("tThread %d: job %d delay = %dn",

thrd_num, count, delay_time);

}

printf("Thread %d finishedn", thrd_num);

pthread_exit(NULL);

}

int main(void)

{

pthread_t thread[THREAD_NUMBER];

int no = 0, res;

void * thrd_ret;

srand(time(NULL));

/* 互斥鎖初始化 */

pthread_mutex_init(&mutex, NULL);

for (no = 0; no < THREAD_NUMBER; no++)

{

res = pthread_create(&thread[no], NULL, thrd_func, (void*)no);

if (res != 0)

{

printf("Create thread %d failedn", no);

exit(res);

}

}

printf("Create treads successn Waiting for threads to finish...n");

for (no = 0; no < THREAD_NUMBER; no++)

{

res = pthread_join(thread[no], &thrd_ret);

if (!res)

{

printf("Thread %d joinedn", no);

}

else

{

printf("Thread %d join failedn", no);

}

/* 互斥鎖解鎖 */

pthread_mutex_unlock(&mutex);

}

pthread_mutex_destroy(&mutex);

return 0;

}

該實例的運行結果如下所示。這里3個線程之間的運行順序跟創(chuàng)建線程的順序相同。

$ ./thread_mutex

Create treads success

Waiting for threads to finish...

Thread 0 is starting

Thread 0: job 0 delay = 7

Thread 0: job 1 delay = 7

Thread 0: job 2 delay = 6

Thread 0 finished

Thread 0 joined

Thread 1 is starting

Thread 1: job 0 delay = 3

Thread 1: job 1 delay = 5

Thread 1: job 2 delay = 10

Thread 1 finished

Thread 1 joined

Thread 2 is starting

Thread 2: job 0 delay = 6

Thread 2: job 1 delay = 10

Thread 2: job 2 delay = 8

Thread 2 finished

Thread 2 joined

2.信號量線程控制

(1)信號量說明。

在第8章中已經講到,信號量也就是操作系統(tǒng)中所用到的PV原子操作,它廣泛用于進程或線程間的同步與互斥。信號量本質上是一個非負的整數(shù)計數(shù)器,它被用來控制對公共資源的訪問。這里先來簡單復習一下PV原子操作的工作原理。

PV原子操作是對整數(shù)計數(shù)器信號量sem的操作。一次P操作使sem減一,而一次V操作使sem加一。進程(或線程)根據(jù)信號量的值來判斷是否對公共資源具有訪問權限。當信號量sem的值大于等于零時,該進程(或線程)具有公共資源的訪問權限;相反,當信號量sem的值小于零時,該進程(或線程)就將阻塞直到信號量sem的值大于等于0為止。

PV原子操作主要用于進程或線程間的同步和互斥這兩種典型情況。若用于互斥,幾個進程(或線程)往往只設置一個信號量sem,它們的操作流程如圖9.2所示。

當信號量用于同步操作時,往往會設置多個信號量,并安排不同的初始值來實現(xiàn)它們之間的順序執(zhí)行,它們的操作流程如圖9.3所示。

圖9.2 信號量互斥操作 圖9.3 信號量同步操作

(2)函數(shù)說明。

Linux實現(xiàn)了POSIX的無名信號量,主要用于線程間的互斥與同步。這里主要介紹幾個常見函數(shù)。

n sem_init()用于創(chuàng)建一個信號量,并初始化它的值。

n sem_wait()和sem_trywait()都相當于P操作,在信號量大于零時它們都能將信號量的值減一,兩者的區(qū)別在于若信號量小于零時,sem_wait()將會阻塞進程,而sem_trywait()則會立即返回。

n sem_post()相當于V操作,它將信號量的值加一同時發(fā)出信號來喚醒等待的進程。

n sem_getvalue()用于得到信號量的值。

n sem_destroy()用于刪除信號量。

(3)函數(shù)格式。

表9.7列出了sem_init()函數(shù)的語法要點。

表9.7 sem_init()函數(shù)語法要點

所需頭文件

#include <semaphore.h>

函數(shù)原型

int sem_init(sem_t *sem,int pshared,unsigned int value)

函數(shù)傳入值

sem:信號量指針

pshared:決定信號量能否在幾個進程間共享。由于目前Linux還沒有實現(xiàn)進程間共享信號量,所以這個值只能夠取0,就表示這個信號量是當前進程的局部信號量

value:信號量初始化值

函數(shù)返回值

成功:0

出錯:-1

表9.8列出了sem_wait()等函數(shù)的語法要點。

表9.8 sem_wait()等函數(shù)語法要點

所需頭文件

#include <pthread.h>

函數(shù)原型

int sem_wait(sem_t *sem)
int sem_trywait(sem_t *sem)
int sem_post(sem_t *sem)
int sem_getvalue(sem_t *sem)
int sem_destroy(sem_t *sem)

函數(shù)傳入值

sem:信號量指針

函數(shù)返回值

成功:0

出錯:-1

(4)使用實例。

在前面已經通過互斥鎖同步機制實現(xiàn)了多線程的順序執(zhí)行。下面的例子是用信號量同步機制實現(xiàn)3個線程之間的有序執(zhí)行,只是執(zhí)行順序是跟創(chuàng)建線程的順序相反。

/*thread_sem.c*/

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#include <semaphore.h>

#define THREAD_NUMBER 3 /* 線程數(shù) */

#define REPEAT_NUMBER 3 /* 每個線程中的小任務數(shù) */

#define DELAY_TIME_LEVELS 10.0 /*小任務之間的最大時間間隔*/

sem_t sem[THREAD_NUMBER];

void *thrd_func(void *arg)

{

int thrd_num = (int)arg;

int delay_time = 0;

int count = 0;

/* 進行P操作 */

sem_wait(&sem[thrd_num]);

printf("Thread %d is startingn", thrd_num);

for (count = 0; count < REPEAT_NUMBER; count++)

{

delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1;

sleep(delay_time);

printf("tThread %d: job %d delay = %dn",

thrd_num, count, delay_time);

}

printf("Thread %d finishedn", thrd_num);

pthread_exit(NULL);

}

int main(void)

{

pthread_t thread[THREAD_NUMBER];

int no = 0, res;

void * thrd_ret;

srand(time(NULL));

for (no = 0; no < THREAD_NUMBER; no++)

{

sem_init(&sem[no], 0, 0);

res = pthread_create(&thread[no], NULL, thrd_func, (void*)no);

if (res != 0)

{

printf("Create thread %d failedn", no);

exit(res);

}

}

printf("Create treads successn Waiting for threads to finish...n");

/* 對最后創(chuàng)建的線程的信號量進行V操作 */

sem_post(&sem[THREAD_NUMBER - 1]);

for (no = THREAD_NUMBER - 1; no >= 0; no--)

{

res = pthread_join(thread[no], &thrd_ret);

if (!res)

{

printf("Thread %d joinedn", no);

}

else

{

printf("Thread %d join failedn", no);

}

/* 進行V操作 */

sem_post(&sem[(no + THREAD_NUMBER - 1) % THREAD_NUMBER]);

}

for (no = 0; no < THREAD_NUMBER; no++)

{

/* 刪除信號量 */

sem_destroy(&sem[no]);

}

return 0;

}

該程序運行結果如下所示:

$ ./thread_sem

Create treads success

Waiting for threads to finish...

Thread 2 is starting

Thread 2: job 0 delay = 9

Thread 2: job 1 delay = 5

Thread 2: job 2 delay = 10

Thread 2 finished

Thread 2 joined

Thread 1 is starting

Thread 1: job 0 delay = 7

Thread 1: job 1 delay = 4

Thread 1: job 2 delay = 4

Thread 1 finished

Thread 1 joined

Thread 0 is starting

Thread 0: job 0 delay = 10

Thread 0: job 1 delay = 8

Thread 0: job 2 delay = 9

Thread 0 finished

Thread 0 joined

9.2.3 線程屬性

(1)函數(shù)說明。

pthread_create()函數(shù)的第二個參數(shù)(pthread_attr_t *attr)表示線程的屬性。在上一個實例中,將該值設為NULL,也就是采用默認屬性,線程的多項屬性都是可以更改的。這些屬性主要包括綁定屬性、分離屬性、堆棧地址、堆棧大小以及優(yōu)先級。其中系統(tǒng)默認的屬性為非綁定、非分離、缺省1M的堆棧以及與父進程同樣級別的優(yōu)先級。下面首先對綁定屬性和分離屬性的基本概念進行講解。

n 綁定屬性。

前面已經提到,Linux中采用“一對一”的線程機制,也就是一個用戶線程對應一個內核線程。綁定屬性就是指一個用戶線程固定地分配給一個內核線程,因為CPU時間片的調度是面向內核線程(也就是輕量級進程)的,因此具有綁定屬性的線程可以保證在需要的時候總有一個內核線程與之對應。而與之對應的非綁定屬性就是指用戶線程和內核線程的關系不是始終固定的,而是由系統(tǒng)來控制分配的。

n 分離屬性。

分離屬性是用來決定一個線程以什么樣的方式來終止自己。在非分離情況下,當一個線程結束時,它所占用的系統(tǒng)資源并沒有被釋放,也就是沒有真正的終止。只有當pthread_join()函數(shù)返回時,創(chuàng)建的線程才能釋放自己占用的系統(tǒng)資源。而在分離屬性情況下,一個線程結束時立即釋放它所占有的系統(tǒng)資源。這里要注意的一點是,如果設置一個線程的分離屬性,而這個線程運行又非???,那么它很可能在pthread_create()函數(shù)返回之前就終止了,它終止以后就可能將線程號和系統(tǒng)資源移交給其他的線程使用,這時調用pthread_create()的線程就得到了錯誤的線程號。

這些屬性的設置都是通過特定的函數(shù)來完成的,通常首先調用pthread_attr_init()函數(shù)進行初始化,之后再調用相應的屬性設置函數(shù),最后調用pthread_attr_destroy()函數(shù)對分配的屬性結構指針進行清理和回收。設置綁定屬性的函數(shù)為pthread_attr_setscope(),設置線程分離屬性的函數(shù)為pthread_attr_setdetachstate(),設置線程優(yōu)先級的相關函數(shù)為pthread_attr_getschedparam()(獲取線程優(yōu)先級)和pthread_attr_setschedparam()(設置線程優(yōu)先級)。在設置完這些屬性后,就可以調用pthread_create()函數(shù)來創(chuàng)建線程了。

(2)函數(shù)格式。

表9.9列出了pthread_attr_init()函數(shù)的語法要點。

表9.9 pthread_attr_init()函數(shù)語法要點

所需頭文件

#include <pthread.h>

函數(shù)原型

int pthread_attr_init(pthread_attr_t *attr)

函數(shù)傳入值

attr:線程屬性結構指針

函數(shù)返回值

成功:0

出錯:返回錯誤碼

表9.10列出了pthread_attr_setscope()函數(shù)的語法要點。

表9.10 pthread_attr_setscope()函數(shù)語法要點

所需頭文件

#include <pthread.h>

函數(shù)原型

int pthread_attr_setscope(pthread_attr_t *attr, int scope)

函數(shù)傳入值

attr:線程屬性結構指針

scope

PTHREAD_SCOPE_SYSTEM:綁定

PTHREAD_SCOPE_PROCESS:非綁定

函數(shù)返回值

成功:0

出錯:-1

表9.11列出了pthread_attr_setdetachstate()函數(shù)的語法要點。

表9.11 pthread_attr_setdetachstate()函數(shù)語法要點

所需頭文件

#include <pthread.h>

函數(shù)原型

int pthread_attr_setscope(pthread_attr_t *attr, int detachstate)

函數(shù)傳入值

attr:線程屬性

detachstate

PTHREAD_CREATE_DETACHED:分離

PTHREAD _CREATE_JOINABLE:非分離

函數(shù)返回值

成功:0

出錯:返回錯誤碼

表9.12列出了pthread_attr_getschedparam()函數(shù)的語法要點。

表9.12 pthread_attr_getschedparam()函數(shù)語法要點

所需頭文件

#include <pthread.h>

函數(shù)原型

int pthread_attr_getschedparam (pthread_attr_t *attr, struct sched_param *param)

函數(shù)傳入值

attr:線程屬性結構指針

param:線程優(yōu)先級

函數(shù)返回值

成功:0

出錯:返回錯誤碼

表9.13列出了pthread_attr_setschedparam()函數(shù)的語法要點。

表9.13 pthread_attr_setschedparam()函數(shù)語法要點

所需頭文件

#include <pthread.h>

函數(shù)原型

int pthread_attr_setschedparam (pthread_attr_t *attr, struct sched_param *param)

函數(shù)傳入值

attr:線程屬性結構指針

param:線程優(yōu)先級

函數(shù)返回值

成功:0

出錯:返回錯誤碼

(3)使用實例。

下面的實例是在我們已經很熟悉的實例的基礎上增加線程屬性設置的功能。為了避免不必要的復雜性,這里就創(chuàng)建一個線程,這個線程具有綁定和分離屬性,而且主線程通過一個finish_flag標志變量來獲得線程結束的消息,而并不調用pthread_join()函數(shù)。

/*thread_attr.c*/

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

#define REPEAT_NUMBER 3 /* 線程中的小任務數(shù) */

#define DELAY_TIME_LEVELS 10.0 /* 小任務之間的最大時間間隔 */

int finish_flag = 0;

void *thrd_func(void *arg)

{

int delay_time = 0;

int count = 0;

printf("Thread is startingn");

for (count = 0; count < REPEAT_NUMBER; count++)

{

delay_time = (int)(rand() * DELAY_TIME_LEVELS/(RAND_MAX)) + 1;

sleep(delay_time);

printf("tThread : job %d delay = %dn", count, delay_time);

}

printf("Thread finishedn");

finish_flag = 1;

pthread_exit(NULL);

}

int main(void)

{

pthread_t thread;

pthread_attr_t attr;

int no = 0, res;

void * thrd_ret;

srand(time(NULL));

/* 初始化線程屬性對象 */

res = pthread_attr_init(&attr);

if (res != 0)

{

printf("Create attribute failedn");

exit(res);

}

/* 設置線程綁定屬性 */

res = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);

/* 設置線程分離屬性 */

res += pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

if (res != 0)

{

printf("Setting attribute failedn");

exit(res);

}

res = pthread_create(&thread, &attr, thrd_func, NULL);

if (res != 0)

{

printf("Create thread failedn");

exit(res);

}

/* 釋放線程屬性對象 */

pthread_attr_destroy(&attr);

printf("Create tread successn");

while(!finish_flag)

{

printf("Waiting for thread to finish...n");

sleep(2);

}

return 0;

}

接下來可以在線程運行前后使用“free”命令查看內存的使用情況。以下是運行結果:

$ ./thread_attr

Create tread success

Waiting for thread to finish...

Thread is starting

Waiting for thread to finish...

Thread : job 0 delay = 3

Waiting for thread to finish...

Thread : job 1 delay = 2

Waiting for thread to finish...

Waiting for thread to finish...

Waiting for thread to finish...

Waiting for thread to finish...

Thread : job 2 delay = 9

Thread finished

/* 程序運行之前 */

$ free

total used free shared buffers cached

Mem: 255556 191940 63616 10 5864 61360

-/+ buffers/cache: 124716 130840

Swap: 377488 18352 359136

/* 程序運行之中 */

$ free

total used free shared buffers cached

Mem: 255556 191948 63608 10 5888 61336

-/+ buffers/cache: 124724 130832

Swap: 377488 18352 359136

/* 程序運行之后 */

$ free

total used free shared buffers cached

Mem: 255556 191940 63616 10 5904 61320

-/+ buffers/cache: 124716 130840

Swap: 377488 18352 359136

可以看到,線程在運行結束后就收回了系統(tǒng)資源,并釋放內存。

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

CPU親和度通過限制進程或線程可以運行的CPU核心集合,使得它們只能在指定的CPU核心上執(zhí)行。這可以減少CPU緩存的失效次數(shù),提高緩存命中率,從而提升系統(tǒng)性能。

關鍵字: Linux 嵌入式

在Linux系統(tǒng)性能優(yōu)化中,內存管理與網絡連接處理是兩大核心領域。vm.swappiness與net.core.somaxconn作為關鍵內核參數(shù),直接影響系統(tǒng)在高負載場景下的穩(wěn)定性與響應速度。本文通過實戰(zhàn)案例解析這兩個...

關鍵字: Linux 內存管理

對于LLM,我使用b谷歌Gemini的免費層,所以唯一的成本是n8n托管。在使用了n8n Cloud的免費積分后,我決定將其托管在Railway上(5美元/月)。然而,由于n8n是開源的,您可以在自己的服務器上托管它,而...

關鍵字: 人工智能 n8n Linux

在Linux系統(tǒng)管理中,權限控制是安全運維的核心。本文通過解析/etc/sudoers文件配置與組策略的深度應用,結合某金融企業(yè)生產環(huán)境案例(成功攔截98.7%的非法提權嘗試),揭示精細化權限管理的關鍵技術點,包括命令別...

關鍵字: Linux 用戶權限 sudoers文件

Linux內核中的信號量(Semaphore)是一種用于資源管理的同步原語,它允許多個進程或線程對共享資源進行訪問控制。信號量的主要作用是限制對共享資源的并發(fā)訪問數(shù)量,從而防止系統(tǒng)過載和數(shù)據(jù)不一致的問題。

關鍵字: Linux 嵌入式

在云計算與容器化技術蓬勃發(fā)展的今天,Linux網絡命名空間(Network Namespace)已成為構建輕量級虛擬網絡的核心組件。某頭部互聯(lián)網企業(yè)通過命名空間技術將測試環(huán)境資源消耗降低75%,故障隔離效率提升90%。本...

關鍵字: Linux 云計算

在Linux內核4.18+和主流發(fā)行版(RHEL 8/Ubuntu 20.04+)全面轉向nftables的背景下,某電商平臺通過遷移將防火墻規(guī)則處理效率提升40%,延遲降低65%。本文基于真實生產環(huán)境案例,詳解從ipt...

關鍵字: nftables Linux

在Linux設備驅動開發(fā)中,等待隊列(Wait Queue)是實現(xiàn)進程睡眠與喚醒的核心機制,它允許進程在資源不可用時主動放棄CPU,進入可中斷睡眠狀態(tài),待資源就緒后再被喚醒。本文通過C語言模型解析等待隊列的實現(xiàn)原理,結合...

關鍵字: 驅動開發(fā) C語言 Linux

在Unix/Linux進程間通信中,管道(pipe)因其簡單高效被廣泛使用,但默認的半雙工特性和無同步機制容易導致數(shù)據(jù)競爭。本文通過父子進程雙向通信案例,深入分析互斥鎖與狀態(tài)機在管道同步中的應用,實現(xiàn)100%可靠的數(shù)據(jù)傳...

關鍵字: 管道通信 父子進程 Linux

RTOS :RTOS的核心優(yōu)勢在于其實時性。它采用搶占式調度策略,確保高優(yōu)先級任務能夠立即獲得CPU資源,從而在最短時間內完成處理。RTOS的實時性是通過嚴格的時間管理和任務調度算法實現(xiàn)的,能夠滿足對時間敏感性要求極高的...

關鍵字: Linux RTOS
關閉