您好,登錄后才能下訂單哦!
LINUX系統編程之線程
情景:
在雙核虛擬機中有兩個線程函數執行以下功能:
線程一:printf("hello\n");
線程二:printf("world\n");
程序運行時在單核狀態下和雙核狀態下兩個線程的執行順序不一樣,請問它們是根據怎樣的規則進行調度的?
進程擁有自己的數據段,代碼段,堆棧,占用資源多,開銷大,通信不方便
為了減少系統開銷,從進程中演化出了線程
線程存在于進程中,使用進程的資源
一、概述
線程是CPU調度和分配的基本單位,存在于進程中,是進程中的獨立控制流
進程是系統中程序執行和資源分配的基本單位
線程自己不擁有資源
進程默認有一個控制線程(主線程)
線程依賴于進程存在,進程結束線程也結束
線程占用空間少
目的:
多任務程序設計
并發程序設計
網絡程序
數據共享
多CPU并行
二、操作
void *fun(void *arg)
注意線程函數參數和返回值類型
pthread_t pth;
創建線程pthread_create(&pth, NULL, fun, (void *)arg);(可用結構體或數組傳遞多個參數)
等待線程結束回收其資源pthread_join(pth, NULL);
分離線程pthread_detach(pth);
退出線程pthread_exit();
取消線程pthread_cancle();
取消狀態pthread_setcancelstate();
取消類型pthread_setcanceltype();
設置取消點pthread_testcancel();
清理pthread_cleanup_push();pthread_cleanup_pop();兩個函數必須成對存在
編譯gcc a.c 加-lpthread
gtk編程中多個線程可能使用同一資源照成界面凍結,所以要線程互斥
可使用gtk_threads_enter();和gtk_threads_leave();實現
三、線程的同步和互斥
互斥:多個任務訪問同一公共資源,同一時刻只有一個任務可以訪問
互斥鎖和信號量
1.互斥鎖:mutex,上鎖解鎖兩種狀態,解鎖必須由上鎖者完成
申請mutex,如果lock則阻塞申請者
pthread_mutex_t mutex;
pthread_mutex_lock(&mutex);
pthread_mutex_trylock(&mutex);
pthread_mutex_unlock(&mutex);
pthread_mutex_destroy(&mutex);
2.信號量
非負的整數計數器
對信號量進行減操作,如果為0則阻塞
PV原語,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);
通過信號量同步操作實現多任務之間按照順序運行
線程:無名信號量,進程:有名信號量
一個任務一個信號量
有名信號量
sem_t *sem_open("sem", O_RDWR);
sem_close(sem);
sem_unlink("sem");
有名信號量的名字在程序中和文件系統中不一樣
有名信號量會保存之前的值所以使用前應該先刪除再創建
實例:
有一個倉庫生產者負責生產產品,并放入倉庫,消費者從倉庫拿走產品
要求倉
庫每次只能入一人
倉庫中最多存放10個產品,倉庫滿時不能再放入產品
倉庫空時不能再從中取出產品
生產消費速度不同
思路:
生產和消費各一個線程,倉庫為互斥,假設容量為10,庫存為3
假設生產速度比消費速度快
信號量的值等于剩余產品
#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;
}
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。