新聞中心
Linux是目前最為流行的操作系統(tǒng)之一,它的強(qiáng)大之處在于其開(kāi)放性和靈活性。作為一名Linux開(kāi)發(fā)者或者系統(tǒng)管理員,深入了解Linux線(xiàn)程是非常重要的一步。

本文將通過(guò)實(shí)例來(lái)幫助讀者掌握Linux線(xiàn)程的基本知識(shí)。我們將使用C語(yǔ)言和Linux的pthread庫(kù)來(lái)創(chuàng)建、管理和控制線(xiàn)程,并介紹一些基本的線(xiàn)程概念和技術(shù)。
為了更好地理解本文中的示例代碼,我們假設(shè)讀者已經(jīng)了解C語(yǔ)言基礎(chǔ)和Linux基礎(chǔ)知識(shí),并熟悉使用Linux的命令行界面。
一、線(xiàn)程基礎(chǔ)概念
在開(kāi)始講解Linux線(xiàn)程之前,我們先了解一些基本概念。
線(xiàn)程是計(jì)算機(jī)操作系統(tǒng)中的一個(gè)執(zhí)行單位,它是作系統(tǒng)獨(dú)立調(diào)度和管理的最小運(yùn)行單位。一個(gè)進(jìn)程可以包含多個(gè)線(xiàn)程,多個(gè)線(xiàn)程可以同時(shí)執(zhí)行,并共享進(jìn)程的資源。
與進(jìn)程不同,線(xiàn)程之間共享了進(jìn)程的資源(堆、全局變量、靜態(tài)變量等),因此線(xiàn)程間的通信也更加方便。此外,線(xiàn)程的創(chuàng)建和銷(xiāo)毀比進(jìn)程更加輕量級(jí)和快速。因此,線(xiàn)程在多任務(wù)操作中有著重要的應(yīng)用。
二、線(xiàn)程的創(chuàng)建和銷(xiāo)毀
接下來(lái)我們通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)創(chuàng)建和銷(xiāo)毀線(xiàn)程。
#include
#include
#include
void *hello_thread(void *arg)
{
int i;
for (i = 0; i
{
printf(“hello thread!\n”);
sleep(1);
}
return NULL;
}
int mn(int argc, char *argv[])
{
pthread_t tid;
int ret;
ret = pthread_create(&tid, NULL, hello_thread, NULL);
if (ret != 0)
{
printf(“pthread_create error:ret=%d\n”, ret);
return -1;
}
printf(“create thread %lu\n”, tid);
pthread_join(tid, NULL);
return 0;
}
上述代碼中,我們首先定義了一個(gè)hello_thread函數(shù),用于線(xiàn)程執(zhí)行的任務(wù)。接著,我們?cè)趍n函數(shù)中使用pthread_create函數(shù)創(chuàng)建了一個(gè)新的線(xiàn)程,傳入線(xiàn)程ID、線(xiàn)程屬性、線(xiàn)程函數(shù)以及傳遞給線(xiàn)程函數(shù)的參數(shù)。線(xiàn)程創(chuàng)建成功后,主線(xiàn)程會(huì)打印出創(chuàng)建的線(xiàn)程ID。我們使用pthread_join函數(shù)等待線(xiàn)程的結(jié)束。
你可以使用gcc編譯該代碼,如下所示:
$ gcc -o thread thread.c -lpthread
執(zhí)行編譯后的可執(zhí)行文件,你將看到如下輸出:
create thread 3079033696
hello thread!
hello thread!
hello thread!
上述示例中,我們調(diào)用了pthread_create函數(shù)來(lái)創(chuàng)建一個(gè)線(xiàn)程。pthread_create函數(shù)的之一個(gè)參數(shù)傳入要?jiǎng)?chuàng)建的線(xiàn)程ID,第二個(gè)參數(shù)指定線(xiàn)程的屬性(通常為NULL),第三個(gè)參數(shù)是線(xiàn)程函數(shù)的指針(函數(shù)名不需加括號(hào)),最后一個(gè)參數(shù)是傳遞給線(xiàn)程函數(shù)的參數(shù)(通常為NULL)。
線(xiàn)程創(chuàng)建成功后,主線(xiàn)程繼續(xù)執(zhí)行,而新線(xiàn)程開(kāi)始執(zhí)行其指定的函數(shù)。在我們的示例中,新線(xiàn)程是輸出”hello thread!” 三次,每次隔1秒鐘,然后退出。當(dāng)線(xiàn)程函數(shù)返回NULL時(shí),表示線(xiàn)程任務(wù)結(jié)束。主線(xiàn)程調(diào)用pthread_join等待子線(xiàn)程完成。
三、線(xiàn)程同步
在多線(xiàn)程編程中,線(xiàn)程同步是非常重要的概念。特別是在共享資源的情況下,要確保線(xiàn)程的正確性和一致性。
我們以生產(chǎn)者消費(fèi)者為例,講述如何使用線(xiàn)程同步來(lái)確保數(shù)據(jù)的正確性。這里我們假設(shè)有一個(gè)環(huán)形緩沖區(qū),它被一個(gè)單獨(dú)的線(xiàn)程用于生產(chǎn)數(shù)據(jù),一個(gè)線(xiàn)程用于消費(fèi)數(shù)據(jù)。生產(chǎn)者在存儲(chǔ)數(shù)據(jù)時(shí)會(huì)檢查環(huán)形緩沖區(qū)是否已滿(mǎn),消費(fèi)者在取出數(shù)據(jù)時(shí)會(huì)檢查緩沖區(qū)是否為空。
我們使用兩個(gè)互斥鎖(pthread_mutex_t)和兩個(gè)條件變量(pthread_cond_t)來(lái)實(shí)現(xiàn)上述場(chǎng)景。
#include
#include
#include
#define BUFFER_SIZE 4
int buffer[BUFFER_SIZE];
int g_write_idx = 0;
int g_read_idx = 0;
pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t g_notempty_cond = PTHREAD_COND_INITIALIZER;
pthread_cond_t g_notfull_cond = PTHREAD_COND_INITIALIZER;
void *producer_thread(void *arg)
{
int i;
for (i = 0; i
{
pthread_mutex_lock(&g_mutex);
while (g_write_idx == BUFFER_SIZE)
{
pthread_cond_wt(&g_notfull_cond, &g_mutex);
}
buffer[g_write_idx++] = i;
printf(“produce: %d\n”, i);
pthread_cond_signal(&g_notempty_cond);
pthread_mutex_unlock(&g_mutex);
}
return NULL;
}
void *consumer_thread(void *arg)
{
int i, data;
for (i = 0; i
{
pthread_mutex_lock(&g_mutex);
while (g_write_idx == 0)
{
pthread_cond_wt(&g_notempty_cond, &g_mutex);
}
data = buffer[g_read_idx++];
printf(“consume: %d\n”, data);
pthread_cond_signal(&g_notfull_cond);
pthread_mutex_unlock(&g_mutex);
}
return NULL;
}
int mn(int argc, char *argv[])
{
pthread_t producer_tid, consumer_tid;
pthread_create(&producer_tid, NULL, producer_thread, NULL);
pthread_create(&consumer_tid, NULL, consumer_thread, NULL);
pthread_join(producer_tid, NULL);
pthread_join(consumer_tid, NULL);
return 0;
}
上述代碼中,我們首先定義BUFFER_SIZE表示緩沖區(qū)的大小,然后定義g_write_idx和g_read_idx分別表示寫(xiě)下標(biāo)和讀下標(biāo)。接著我們定義了兩個(gè)互斥鎖g_mutex和兩個(gè)條件變量g_notempty_cond和g_notfull_cond。
在生產(chǎn)者線(xiàn)程中,我們使用pthread_mutex_lock函數(shù)來(lái)訪(fǎng)問(wèn)共享資源buffer和g_write_idx,如果發(fā)現(xiàn)緩沖區(qū)已滿(mǎn),線(xiàn)程將使用pthread_cond_wt函數(shù)等待g_notfull_cond條件變量。當(dāng)消費(fèi)者取出數(shù)據(jù)后,生產(chǎn)者線(xiàn)程將使用pthread_cond_signal函數(shù)通知消費(fèi)者線(xiàn)程緩沖區(qū)中已經(jīng)有可讀數(shù)據(jù),然后釋放互斥鎖。
在消費(fèi)者線(xiàn)程中,我們也使用pthread_mutex_lock函數(shù)來(lái)訪(fǎng)問(wèn)共享資源buffer和g_read_idx,如果發(fā)現(xiàn)緩沖區(qū)為空,線(xiàn)程將使用pthread_cond_wt函數(shù)等待g_notempty_cond條件變量。當(dāng)生產(chǎn)者存儲(chǔ)了新數(shù)據(jù)后,消費(fèi)者線(xiàn)程將使用pthread_cond_signal函數(shù)通知生產(chǎn)者線(xiàn)程緩沖區(qū)中已經(jīng)有空閑空間,然后釋放互斥鎖。
在主函數(shù)中,我們調(diào)用pthread_create函數(shù)來(lái)創(chuàng)建生產(chǎn)者線(xiàn)程和消費(fèi)者線(xiàn)程,并使用pthread_join等待兩個(gè)線(xiàn)程結(jié)束。
四、線(xiàn)程池
線(xiàn)程池是一種常見(jiàn)的多線(xiàn)程技術(shù),它可以在應(yīng)用程序中管理和調(diào)度大量線(xiàn)程。線(xiàn)程池中的線(xiàn)程通常是預(yù)先創(chuàng)建好的,它們將等待任務(wù)的到來(lái)并處理任務(wù)。使用線(xiàn)程池可以避免線(xiàn)程頻繁創(chuàng)建和銷(xiāo)毀的開(kāi)銷(xiāo),提高多線(xiàn)程的效率。
下面我們介紹如何使用線(xiàn)程池來(lái)執(zhí)行一個(gè)簡(jiǎn)單的任務(wù)。
#include
#include
#include
#include
#include
#define DEFAULT_THREAD_NUM 3
typedef struct task_s
{
void *(*task_func)(void *);
void *arg;
struct task_s *next;
} task_t;
typedef struct threadpool_s
{
int thread_num;
pthread_t *threads;
pthread_mutex_t lock;
pthread_cond_t cond;
task_t *head;
task_t *tl;
int shutdown;
} threadpool_t;
void *threadpool_worker(void *arg)
{
threadpool_t *pool = (threadpool_t *)arg;
task_t *task = NULL;
while (1)
{
pthread_mutex_lock(&pool->lock);
while (!pool->shutdown && !pool->head)
{
pthread_cond_wt(&pool->cond, &pool->lock);
}
if (pool->shutdown)
{
pthread_mutex_unlock(&pool->lock);
pthread_exit(NULL);
}
task = pool->head;
pool->head = task->next;
if (pool->head == NULL)
{
pool->tl = NULL;
}
pthread_mutex_unlock(&pool->lock);
printf(“Do something…\n”);
task->task_func(task->arg);
free(task);
}
return NULL;
}
int threadpool_create(threadpool_t *pool, int thread_num)
{
int i;
pool->thread_num = thread_num;
pool->threads = (pthread_t *)malloc(sizeof(pthread_t) * thread_num);
if (pool->threads == NULL)
{
perror(“malloc”);
return -1;
}
pool->head = NULL;
pool->tl = NULL;
if (pthread_mutex_init(&pool->lock, NULL) != 0)
{
perror(“pthread_mutex_init”);
return -1;
}
if (pthread_cond_init(&pool->cond, NULL) != 0)
{
perror(“pthread_cond_init”);
return -1;
}
pool->shutdown = 0;
for (i = 0; i
{
if (pthread_create(&pool->threads[i], NULL, threadpool_worker, (void *)pool) != 0)
{
perror(“pthread_create”);
return -1;
}
}
return 0;
}
void threadpool_destroy(threadpool_t *pool)
{
int i;
task_t *task;
if (pool->shutdown)
{
return;
}
pool->shutdown = 1;
pthread_cond_broadcast(&pool->cond);
for (i = 0; i thread_num; i++)
{
pthread_join(pool->threads[i], NULL);
}
free(pool->threads);
while (pool->head)
{
task = pool->head;
pool->head = task->next;
free(task);
}
pool->head = NULL;
pool->tl = NULL;
pthread_mutex_destroy(&pool->lock);
pthread_cond_destroy(&pool->cond);
}
int threadpool_add_task(threadpool_t *pool, void *(*task_func)(void *), void *arg)
{
task_t *task = (task_t *)malloc(sizeof(task_t));
if (task == NULL)
{
return -1;
}
task->next = NULL;
task->task_func = task_func;
task->arg = arg;
pthread_mutex_lock(&pool->lock);
if (pool->tl == NULL)
{
pool->head = task;
pool->tl = task;
}
else
{
pool->tl->next = task;
pool->tl = task;
}
pthread_cond_signal(&pool->cond);
pthread_mutex_unlock(&pool->lock);
return 0;
}
void *task_func(void *arg)
{
char *str = (char *)arg;
sleep(1);
printf(“Task is doing (%s)…\n”, str);
return NULL;
}
int mn(int argc, const char *argv[])
{
int i;
threadpool_t pool;
if (threadpool_create(&pool, DEFAULT_THREAD_NUM) != 0)
{
perror(“threadpool_create”);
return -1;
}
for (i = 0; i
{
char str[128] = {0};
sprintf(str, “task_%d”, i);
threadpool_add_task(&pool, task_func, strdup(str));
}
sleep(5);
threadpool_destroy(&pool);
return 0;
}
上述代碼中,我們首先定義了一個(gè)task_t結(jié)構(gòu)體,表示任務(wù)的數(shù)據(jù)結(jié)構(gòu)。然后定義了一個(gè)threadpool_t結(jié)構(gòu)體,表示線(xiàn)程池的數(shù)據(jù)結(jié)構(gòu)。
在線(xiàn)程池的創(chuàng)建函數(shù)threadpool_create中,我們首先動(dòng)態(tài)分配了線(xiàn)程數(shù)組,然后初始化了線(xiàn)程池的鎖和條件變量。接著,我們使用pthread_create函數(shù)創(chuàng)建了指定數(shù)量的工作線(xiàn)程,并在這些線(xiàn)程中不斷從線(xiàn)程池中取出任務(wù)進(jìn)行處理。
在線(xiàn)程池的銷(xiāo)毀函數(shù)threadpool_destroy中,我們首先通知所有工作線(xiàn)程退出,然后等待所有線(xiàn)程并成功退出。我們釋放線(xiàn)程數(shù)組和任務(wù)隊(duì)列中的所有任務(wù),銷(xiāo)毀線(xiàn)程池的鎖和條件變量。
在向線(xiàn)程池添加任務(wù)時(shí),我們創(chuàng)建一個(gè)新的任務(wù)并加入到線(xiàn)程池的任務(wù)隊(duì)列中。這里我們使用了pthread_mutex_lock和pthread_cond_signal函數(shù)來(lái)保證多個(gè)線(xiàn)程都正確地訪(fǎng)問(wèn)任務(wù)隊(duì)列。
在任務(wù)的執(zhí)行函數(shù)task_func中,我們僅僅是簡(jiǎn)單地休眠了一秒鐘,然后輸出一個(gè)字符串。
在主函數(shù)中,我們使用threadpool_create函數(shù)來(lái)創(chuàng)建線(xiàn)程池并向線(xiàn)程池中加入了10個(gè)需要執(zhí)行的任務(wù),然后等待5秒鐘后,使用threadpool_destroy函數(shù)銷(xiāo)毀線(xiàn)程池。
成都網(wǎng)站建設(shè)公司-創(chuàng)新互聯(lián),建站經(jīng)驗(yàn)豐富以策略為先導(dǎo)10多年以來(lái)專(zhuān)注數(shù)字化網(wǎng)站建設(shè),提供企業(yè)網(wǎng)站建設(shè),高端網(wǎng)站設(shè)計(jì),響應(yīng)式網(wǎng)站制作,設(shè)計(jì)師量身打造品牌風(fēng)格,熱線(xiàn):028-86922220關(guān)于嵌入式linux系統(tǒng)的問(wèn)題,多線(xiàn)程,基于arm9開(kāi)發(fā)板
1)
linux二進(jìn)制可執(zhí)行文件是無(wú)法得轉(zhuǎn)換為代碼的,所以修改不了代碼,只能找源碼去改,改完了重新交叉編譯再寫(xiě)進(jìn)開(kāi)發(fā)板上。
2)
使用linux多線(xiàn)程問(wèn)題模姿燃,A中滿(mǎn)足條件創(chuàng)建線(xiàn)程B,線(xiàn)程B中滿(mǎn)足條件創(chuàng)建線(xiàn)程C,如果你線(xiàn)程A和B沒(méi)有退出,A和B都會(huì)繼續(xù)執(zhí)行
實(shí)例程序如下:main中十秒后創(chuàng)建線(xiàn)程A ,A中10秒后創(chuàng)建B,B線(xiàn)程十秒后創(chuàng)建線(xiàn)程C,每個(gè)線(xiàn)程中都會(huì)有打印信息,當(dāng)出現(xiàn)pthread A pthread B pthread C同時(shí)出現(xiàn)時(shí),證明三個(gè)線(xiàn)程同時(shí)存活
此程序編譯時(shí)需加-phread參數(shù),例如:cc pthread_join.c -pthread
#include
#include
#include
#include
#include
void * A();//線(xiàn)程函數(shù)聲明
void * B();
void * C();
void * A()
{
pthread_t b;
int i = 0;
while(i
{
if (++i == 10)
pthread_create(&b, NULL, (void *)B, NULL );//創(chuàng)建線(xiàn)程B
sleep(1);
printf(“pthread A\n”);
}
pthread_join(b, NULL);
return 0;
}
void * B()
{
pthread_t c;
int i = 0;
while(i
{
if (++i == 10)
pthread_create(&c, NULL, (void *)C, NULL );/冊(cè)晌/創(chuàng)建線(xiàn)程C
printf(“pthread B\n”);
sleep(1);
}
pthread_join(c, NULL);
return 0;
}
void *C()
{
int i = 0;
while(i
{
printf(“pthread C\n”);
sleep(1);
i++;
}
return 0;
}
int main()
{
pthread_t a;
int i = 0;
while(i
{
if (++i == 10)
pthread_create(&a, NULL, (void *)A, NULL );//創(chuàng)建線(xiàn)程A
printf(“i = %d\n”, i );
sleep(1);
}
pthread_join(a, NULL);
return 0;
}
以上是多線(xiàn)程程序的例子
但是,如果你想一個(gè)程序調(diào)用另一個(gè)程序時(shí),你可以這樣做:
比如你有三個(gè)可執(zhí)行程序a.out b.out c.out
運(yùn)行a.out當(dāng)符合某個(gè)程旦虛序時(shí)使用system(“./b.out”);調(diào)用程序b.out,在b.out程序中以同樣的方法調(diào)用程序c.out。但此時(shí)已經(jīng)不是多線(xiàn)程了,而是三個(gè)不同的進(jìn)程,進(jìn)程a.out b.out 和c.out
也可以在上面的程序中十秒的時(shí)候創(chuàng)建子進(jìn)程后,在子進(jìn)程中以system(“./b.out”);來(lái)運(yùn)行程序b.out
linux下多線(xiàn)程編程問(wèn)題,求各種優(yōu)化
while((p=fork())==-1);//創(chuàng)建進(jìn)程
if(p==0)
{
ret=pthread_create(&id1,NULL,(void *)pthread1, NULL);//創(chuàng)建線(xiàn)程
if(ret!=0) perror(“線(xiàn)程1創(chuàng)建失敗”);
ret=pthread_create(&id2,NULL,(void *)pthread2, NULL);
if(ret!=0) perror(“線(xiàn)程2創(chuàng)建失敗”);
ret=pthread_create(&id3,NULL,(void *)pthread3, NULL);
if(ret!=0) perror(“線(xiàn)程3創(chuàng)建失敗”);
……
pthread_join(id1,NULL);
pthread_join(id2,NULL);
pthread_join(id3,NULL);
………./缺搭侍/結(jié)束線(xiàn)程
exit(0);
}
void pthread1(void *arg)
{
while(time(NULL)
{
if(pthread_mutex_lock(&mutex)!=0)//鎖定數(shù)據(jù) 可以在這里判斷接入次數(shù),現(xiàn)在是寫(xiě)鎖定判斷
{
perror(“鎖定失敗”);
}
else printf(“線(xiàn)程1:鎖定數(shù)據(jù)量\n”);
{
}
if(pthread_mutex_unlock(&mutex)!=0) //數(shù)據(jù)解鎖 這里可以判斷不超過(guò)3次鎖定解鎖
{
perror(“解鎖失敗”);
}
else
printf(“線(xiàn)程1:我已解鎖\n”);
sleep(4);
}
}
其他的你自己補(bǔ)充吧,自己定義幾個(gè)全局變伏吵量控制線(xiàn)程鎖定解鎖邏輯關(guān)系就行
點(diǎn)擊我百度名字,進(jìn)入尋找真相在內(nèi),相信你懂的
線(xiàn)程太頭疼,鎖賴(lài)鎖去會(huì)死人的
linux 線(xiàn)程中,線(xiàn)程宿主函數(shù)是什么意思?宿體函數(shù)又是什么意思?二者有什么區(qū)別?更好能舉個(gè)例子。
宿主函數(shù)是你調(diào)用建立線(xiàn)程的函數(shù),而宿體函數(shù)是你線(xiàn)程運(yùn)行起來(lái)后執(zhí)行的函數(shù)
void f(void *arg);
void ff()
{
/弊逗*…*/
pthread_creat(…., …, f, NULL);
}
上面租舉賣(mài)例子中ff是宿主,f是宿答臘體
linux thread 例子的介紹就聊到這里吧,感謝你花時(shí)間閱讀本站內(nèi)容,更多關(guān)于linux thread 例子,學(xué)習(xí)Linux線(xiàn)程:通過(guò)實(shí)例掌握基本知識(shí),關(guān)于嵌入式linux系統(tǒng)的問(wèn)題,多線(xiàn)程,基于arm9開(kāi)發(fā)板,linux下多線(xiàn)程編程問(wèn)題,求各種優(yōu)化,linux 線(xiàn)程中,線(xiàn)程宿主函數(shù)是什么意思?宿體函數(shù)又是什么意思?二者有什么區(qū)別?更好能舉個(gè)例子。的信息別忘了在本站進(jìn)行查找喔。
創(chuàng)新互聯(lián)【028-86922220】值得信賴(lài)的成都網(wǎng)站建設(shè)公司。多年持續(xù)為眾多企業(yè)提供成都網(wǎng)站建設(shè),成都品牌建站設(shè)計(jì),成都高端網(wǎng)站制作開(kāi)發(fā),SEO優(yōu)化排名推廣服務(wù),全網(wǎng)營(yíng)銷(xiāo)讓企業(yè)網(wǎng)站產(chǎn)生價(jià)值。
本文標(biāo)題:學(xué)習(xí)Linux線(xiàn)程:通過(guò)實(shí)例掌握基本知識(shí)(linuxthread例子)
網(wǎng)頁(yè)地址:http://m.5511xx.com/article/cdgegoh.html


咨詢(xún)
建站咨詢(xún)
