1、核心理論
爲什麼需要線程?
爲了提高完成一個任務的速度,我們創建了多個進程去完成一個任務,但是多個進程間有相同的地方(例如代碼相同,所使用的數據相同),同時工作時就造成了資源的浪費;爲了避免資源浪費,我們進程間相同的部分分割出來,不同的部分就形成了一個小小的線程。線程概念(特點):
· 線程就是“輕量級”的進程。(linux中不存在線程這個機制)
· 線程與創建他的進程共享代碼段、數據段。
· 線程擁有自己的獨立的棧。注意:
1.輕量級是指多個線程線程共享同一個數據段,代碼段,這個代碼段也是創建它的進程的代碼段和數據段,這也是線程與進程的區別。
2.多線程理解:多個線程按一定的順序執行去完成某項任務,這些線程使用共同的數據段,代碼段。
3.當一個進程結束時,那麼他所創建的線程也會結束;如果不想讓其結束那就要用到線程等待函數。
4.再調用線程相關函數時,編譯程序時必須鏈接函數庫::-lpthread
5.爲什麼線程退出函數不使用exit函數?
因爲exit是用來退出進程的,用在線程中會導致創建該線程的進程退出,進程退出了,那麼所創建的所有線程都會退出。
2.函數學習
- 創建線程
函數名:pthread_create
函數原型:int pthread_create(pthread_t *thread,const pthread_attr_t *attr,void *(*start_routine) (void*),void *arg)
函數功能:創建一個進程
所屬頭文件:pthread.h
特別注意:編譯時必須鏈接pthread庫(gcc -lpthread)
返回值:成功返回0,失敗返回一個錯誤號
參數說明:thread
:新創建的線程的id,attr
:創建線程的屬性,start_routine
:指明線程要執行的函數的(線程的入口函數),arg
:線程入口函數的參數,
等待線程結束
函數名:pthread_join
函數原型:pthread_join(pthread_t thread,void **retval)
函數功能:等待線程結束
所屬頭文件:pthread.h
返回值:成功返回0,失敗返回錯誤編號
參數說明:thread
:要等待結束的線程id,retval
:保存線程退出的狀態退出線程
函數名:pthread_exit
函數原型:void pthread_exit(void *retval)
函數功能:退出線程
所屬頭文件:pthread.h
返回值:空
參數說明:retval
:保存返回值
3.線程互斥
概念:
在實際應用中,多個線程往往會訪問同一數據或者資源,爲了避免線程之間相互影響,需要引入線程互斥機制,而互斥鎖(mutex)是互斥機制中的一種。(多進程併發時中引入的是信號量。)初始化互斥鎖函數
pthread_mutex_init獲取互斥鎖函數
pthread_mutex_lock釋放互斥鎖函數
pthread_mutex_unlock
4.綜合實例
- 兩人壘牆問題
(1)線程1
創建線程
等待線程結束
結束線程
(2)線程2
創建線程
等待線程結束
結束線程
#include <pthread.h>
#include <stdio.h>
pthread_t thread[2];
int number = 0;
pthread_mutex_t mut;
void * worker1()
{
int i = 0;
printf("I am worker1!\n");
for (i = 0;i < 10;i++)
{
pthread_mutex_lock(&mut);
number++;
pthread_mutex_unlock(&mut);
printf("worker1 number %d\n",number);
sleep(1);
}
pthread_exit(NULL);
}
void * worker2()
{
int i = 0;
printf("I am worker2!\n");
for (i = 0;i < 10;i++)
{
pthread_mutex_lock(&mut);
number++;
pthread_mutex_unlock(&mut);
printf("worker2 number %d\n",number);
sleep(1);
}
pthread_exit(NULL);
}
int main()
{
pthread_mutex_init(&mut,NULL);
//1.creat worker1 thread
pthread_create(&thread[0],NULL,worker1,NULL);
//2.creat worker2 thread
pthread_create(&thread[1],NULL,worker2,NULL);
//3.wait worker1 thread over
pthread_join(thread[0],NULL);
//4.wait worker2 thread over
pthread_join(thread[1],NULL);
return 0;
}