前言:有個問題感覺一直會被問道:程序和線程的差別?也許之前我會回答:
- 程序:資源配置設定最小機關
- 線程:輕量級的程序 是系統排程的最小機關 由程序建立 多個線程共享程序的資源
但是現在我覺得一個比喻回答的更好:程式就像靜止的火車,程序是運作的火車,線程是運作火車的每節車廂。
個人感覺了解遠比背些概念性東西更好。
一、線程
通常在一個程序中可以包含若幹個線程,當然一個程序中至少有一個線程,不然沒有存在的意義。線程可以利用程序所擁有的資源,在引入線程的作業系統中,通常都是把程序作為配置設定資源的基本機關,而把線程作為獨立運作和獨立排程的基本機關,由于線程比程序更小,基本上不擁有系統資源,故對它的排程所付出的開銷就會小得多,能更高效的提高系統多個程式間并發執行的程度。
1、線程相關函數
- pthread_create函數
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
注:Compile and link with -pthread.//編譯時 要加-lpthread
功能:建立線程
參數1:線程的ID
參數2:NULL
參數3:線程處理函數
參數4: 傳遞給線程處理函數的參數
成功放回0 失敗傳回-1
- pthread_join函數
int pthread_join(pthread_t thread, void **retval);
功能:以阻塞的方式等待指定線程 主線程如果執行到此函數 将阻塞等待子線程結束
程式1-1示範兩個函數用法:
#include"my.h"
void *func(void *p)
{
*(int*)p = 10;
printf("%d\n",*(int *)p);
}
int main()
{
int x=100;
pthread_t id;
int ret = pthread_create(&id,NULL,func,&x);
if(ret<0)
{
perror("pthread_create");
exit(-1);
}
pthread_join(id,NULL);
return 0;
}
注:頭檔案“my.h”為自定義檔案,詳情請參考這篇部落格:http://www.cnblogs.com/liudw-0215/p/8946879.html
運作示範如下圖:

二、信号量
信号量(Semaphore),有時被稱為信号燈,是在多線程環境下使用的一種設施, 它負責協調各個線程, 以保證它們能夠正确、合理的使用公共資源。
1、信号量相關函數
- sem_init函數
sem_t s;
#include <semaphore.h>
int sem_init(sem_t *sem, int pshared, unsigned int value);
格式:sem_init(&s,0,n)
功能:初始化一個信号量的值為value
參數2:是否在程序間使用 一般總是0 表示不在程序間使用
參數3:計數器的初始值
- sem_wait函數
int sem_wait(sem_t *sem);
把計數器減一 它會等待 直到信号量有個非零值才會執行減法操作
如果對值為0的信号量用sem_wait 這個函數會等待 直到其他線程增加該信号量的值 使其不再是0為止
如果對值為2的信号量調用sem_wait 線程會繼續執行 但信号量的值會減一。
如果兩個線程同時在sem_wait調用上等待同一個信号量變為非0值 那麼當信号量 被第三個線程+1 隻有一個等待線程開始對信号量-1
然後繼續執行 另一個線程還繼續等待。
- sem_post函數
int sem_post(sem_t *sem);
功能:把 計數器+1
程式2-1介紹信号量使用
#include"my.h"
sem_t s;
void *fun(void *p)
{
int i;
int *pa = (int *)p;
for(i=0;i<4;i++)
{
sem_wait(&s);//将計數器的值-1
pa[i] +=i;
}
for(i=0;i<4;i++)
{
printf("%-02d",pa[i]);
}
printf("\n");
return NULL;
}
void *fun1(void *p)
{
sem_wait(&s);//将計數器的值-1
puts("fun1 run!");
return NULL;
}
int main()
{
int i=0,ret=0;
int a[5]={0};
sem_init(&s,0,0);//設定信号量的值為0
pthread_t tid[2];
ret = pthread_create(&tid[0],NULL,fun,a);
if(ret<0)
{
perror("pthread_create");
exit(-1);
}
ret = pthread_create(&tid[1],NULL,fun1,a);
if(ret<0)
{
perror("pthread_create");
exit(-1);
}
for(i=0;i<5;i++)
{
sem_post(&s);//将計數器的值+1
}
pthread_join(tid[0],NULL);
pthread_join(tid[1],NULL);
return 0;
}
三、互斥鎖
互斥鎖: 隻要被鎖住,其他任何線程都不可以通路被保護的資源
1、互斥鎖相關函數
pthread_mutex_t m;
pthread_mutex_init(&m,NULL) //初始化互斥量
pthread_mutex_lock(&m);//對一個互斥量加鎖 如果互斥量已經加鎖 函數會一直等待 等到有線程把這個互斥量解鎖後 再去加鎖
pthread_mutex_unlock(&m);//對一個互斥量解鎖 哪個線程加鎖隻能由這個線程解鎖 别的線程不能 解鎖
程式3-1示範互斥鎖應用:
#include"my.h"
pthread_mutex_t m;
void* thread_fun(void *p)
{
int i;
pthread_mutex_lock(&m);//加鎖
for(i=0;i<3;i++)
{
printf("PID:%d tid:%lu\n",getpid(),pthread_self());
sleep(1);
}
pthread_mutex_unlock(&m);//解鎖
pthread_exit(NULL);
}
int main()
{
pthread_mutex_init(&m,NULL);//初始化鎖
int i,ret;
pthread_t tid[3];
for(i=0;i<3;i++)
{
ret = pthread_create(&tid[i],NULL,thread_fun,NULL);
if(ret<0)
{
printf("pthread_create %d error\n",i);
exit(-1);
}
}
for(i=0;i<3;i++)
{
pthread_join(tid[i],NULL);
}
return 0;
}
運作示範如下圖:
總結:主要介紹線程同步的信号量和互斥鎖,以後有時間将更加詳細介紹其中實作原理。
作者:
柳德維出處:
https://www.cnblogs.com/liudw-0215/-------------------------------------------
個性簽名:獨學而無友,則孤陋而寡聞。做一個靈魂有趣的人!
如果覺得這篇文章對你有小小的幫助的話,記得在右下角點個“推薦”哦,部落客在此感謝!
萬水千山總是情,打賞一分行不行,是以如果你心情還比較高興,也是可以掃碼打賞部落客,哈哈哈(っ•̀ω•́)っ⁾⁾!