您好,登錄后才能下訂單哦!
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;
}
免責(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)容。