溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

LINUX系統(tǒng)編程之線程

發(fā)布時(shí)間:2020-05-28 21:52:08 來(lái)源:網(wǎng)絡(luò) 閱讀:519 作者:Czyy1 欄目:系統(tǒng)運(yùn)維

LINUX系統(tǒng)編程之線程

情景:

在雙核虛擬機(jī)中有兩個(gè)線程函數(shù)執(zhí)行以下功能:

線程一:printf("hello\n");

線程二:printf("world\n");

程序運(yùn)行時(shí)在單核狀態(tài)下和雙核狀態(tài)下兩個(gè)線程的執(zhí)行順序不一樣,請(qǐng)問(wèn)它們是根據(jù)怎樣的規(guī)則進(jìn)行調(diào)度的?


進(jìn)程擁有自己的數(shù)據(jù)段,代碼段,堆棧,占用資源多,開(kāi)銷大,通信不方便

為了減少系統(tǒng)開(kāi)銷,從進(jìn)程中演化出了線程

線程存在于進(jìn)程中,使用進(jìn)程的資源


一、概述

線程是CPU調(diào)度和分配的基本單位,存在于進(jìn)程中,是進(jìn)程中的獨(dú)立控制流

進(jìn)程是系統(tǒng)中程序執(zhí)行和資源分配的基本單位

線程自己不擁有資源

進(jìn)程默認(rèn)有一個(gè)控制線程(主線程)

線程依賴于進(jìn)程存在,進(jìn)程結(jié)束線程也結(jié)束

線程占用空間少

目的:

多任務(wù)程序設(shè)計(jì)

并發(fā)程序設(shè)計(jì)

網(wǎng)絡(luò)程序

數(shù)據(jù)共享

多CPU并行


二、操作

void *fun(void *arg)

注意線程函數(shù)參數(shù)和返回值類型

pthread_t pth;

創(chuàng)建線程pthread_create(&pth, NULL, fun, (void *)arg);(可用結(jié)構(gòu)體或數(shù)組傳遞多個(gè)參數(shù))

等待線程結(jié)束回收其資源pthread_join(pth, NULL);

分離線程pthread_detach(pth);

退出線程pthread_exit();

取消線程pthread_cancle();

取消狀態(tài)pthread_setcancelstate();

取消類型pthread_setcanceltype();

設(shè)置取消點(diǎn)pthread_testcancel();

清理pthread_cleanup_push();pthread_cleanup_pop();兩個(gè)函數(shù)必須成對(duì)存在

編譯gcc a.c 加-lpthread


gtk編程中多個(gè)線程可能使用同一資源照成界面凍結(jié),所以要線程互斥

可使用gtk_threads_enter();和gtk_threads_leave();實(shí)現(xiàn)


三、線程的同步和互斥

互斥:多個(gè)任務(wù)訪問(wèn)同一公共資源,同一時(shí)刻只有一個(gè)任務(wù)可以訪問(wèn)

互斥鎖和信號(hào)量

1.互斥鎖:mutex,上鎖解鎖兩種狀態(tài),解鎖必須由上鎖者完成

申請(qǐng)mutex,如果lock則阻塞申請(qǐng)者

pthread_mutex_t mutex;

pthread_mutex_lock(&mutex);

pthread_mutex_trylock(&mutex);

pthread_mutex_unlock(&mutex);

pthread_mutex_destroy(&mutex);


2.信號(hào)量

非負(fù)的整數(shù)計(jì)數(shù)器

對(duì)信號(hào)量進(jìn)行減操作,如果為0則阻塞

PV原語(yǔ),P減,V加

sem_t sem;

sem_init(&sem, 0, 1);

sem_wait(&sem);sem_trywait(&sem);

sem_post(&sem);

int val;

sem_getvalue(&sem, &val);

sem_destroy(&sem);


通過(guò)信號(hào)量同步操作實(shí)現(xiàn)多任務(wù)之間按照順序運(yùn)行

線程:無(wú)名信號(hào)量,進(jìn)程:有名信號(hào)量

一個(gè)任務(wù)一個(gè)信號(hào)量

有名信號(hào)量

sem_t *sem_open("sem", O_RDWR);

sem_close(sem);

sem_unlink("sem");

有名信號(hào)量的名字在程序中和文件系統(tǒng)中不一樣

有名信號(hào)量會(huì)保存之前的值所以使用前應(yīng)該先刪除再創(chuàng)建


實(shí)例:

有一個(gè)倉(cāng)庫(kù)生產(chǎn)者負(fù)責(zé)生產(chǎn)產(chǎn)品,并放入倉(cāng)庫(kù),消費(fèi)者從倉(cāng)庫(kù)拿走產(chǎn)品

要求倉(cāng)

庫(kù)每次只能入一人

倉(cāng)庫(kù)中最多存放10個(gè)產(chǎn)品,倉(cāng)庫(kù)滿時(shí)不能再放入產(chǎn)品

倉(cāng)庫(kù)空時(shí)不能再?gòu)闹腥〕霎a(chǎn)品

生產(chǎn)消費(fèi)速度不同

思路:

生產(chǎn)和消費(fèi)各一個(gè)線程,倉(cāng)庫(kù)為互斥,假設(shè)容量為10,庫(kù)存為3

假設(shè)生產(chǎn)速度比消費(fèi)速度快

信號(hào)量的值等于剩余產(chǎn)品

#include<stdio.h>

#include<sys/stat.h>

#include<fcntl.h>

#include<semaphore.h>

int total=10;//總量

int last=7;//剩余量

sem_t sem_p;

sem_t sem_c;

void *produce(void *arg)

{

// sem_t *temp_semp=(sem_t *)arg;

while(1)

{

// sem_p=total-last;

if(9 >= last)

{

sleep(2);

sem_wait(&sem_p);

last++;

printf("in!last=%d\n",last);

sem_post(&sem_c);

}

}

}

void *cost(void *arg)

{

// sem_t *temp_semp=(sem_t *)arg;

while(1)

{

// sem_c=last;

if(1 <= last)

{

sem_wait(&sem_c);

last--;

printf("out!last=%d\n",last);

sem_post(&sem_p);

sleep(3);

}

}

}

int main()

{

pthread_t pth_p,pth_c;

sem_init(&sem_p,0,total-last);

sem_init(&sem_c,0,last);

printf("init_last=%d\n",last);

pthread_create(&pth_p,NULL,produce,NULL);

pthread_create(&pth_c,NULL,cost,NULL);

while(1);

return 0;

}


向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI