線程機制(並發函數的使用)

一、背景

之前學習過進程的概念,而計算機是不可能只單單運行一個進程的。我們使用fork與exec等系統調用來使進程併發執行。然而對於一個進程而言,該進程一定是有多個函數的,那麼這些函數是否可以併發執行呢?當然是可以的,這一機制就叫做線程機制。

二、一個單線程程序

#include

#include

#define NUM 5

int main()

{

void print_msg(char *);

print_msg("Hello");

print_msg("World\n");

}

void print_msg(char *m)

{

int i;

for(i=0;i

printf("%s",m);

fflush(stdout);

sleep(1);

}

}

這是一個十分簡單的單線程程序,執行結果:

線程機制(併發函數的使用)

可以看到程序先執行完五個hello的輸出,接著執行五個world的輸出。

現在我們考慮的是如何輸出形如hello world\n hello world\n ... 這樣的結果。

這就需要函數併發的執行。

三、簡單的多線程程序

這裡使用了兩個系統調用:pthread_create , pthread_join。

一個用來創建新的線程,後一個用來等待某線程的終止。具體使用可使用man命令查看。

該源程序如下:

#include

#include

#include

#define NUM 5

int main()

{

pthread_t t1,t2;

void *thread(void *);

pthread_create(&t1,NULL,thread,(void *)"Hello");

pthread_create(&t2,NULL,thread,(void *)"World\n");

pthread_join(t1,NULL);

pthread_join(t2,NULL);

}

void *thread(void *m)

{

int i;

for(i=0;i

printf("%s",m);

sleep(1);

}

return NULL;

}

該程序執行結果如下:

線程機制(併發函數的使用)

或許大家會有疑問,為什麼前半部分輸出的helloworld很正常,到後半部分就亂了呢。

原因是thread函數是併發執行的,也可理解為函數在同時運行,所以輸出hello與輸出world的先後順序並不是一定的,

每一次的輸出結果都有可能相同也有可能不相同。

四、共享全局變量

對比進程來學習線程,進程之間有進程之間的通信方式,進程可通過管道、socket、信號、退出/等待來進行進程間的通信。

而線程之間通過什麼通信方式來進行它們之間的分工合作呢?

我們明白,各個線程雖不相同,但都是同在同一個進程中運行的,也就是說,它們之間是共享全局變量的。通過全局變量的使用就可以完成線程之間的通信。

線程之間可通過全局變量進行合作。這裡舉一個例子:

#include

#include

#include

#define NUM 5

int counter = 0;

int main()

{

pthread_t t1;

void *print_count(void *);

int i;

pthread_create(&t1,NULL,print_count,NULL);

for(i=0;i

counter++;

sleep(1);

}

pthread_join(t1,NULL);

}

void *print_count(void *m)

{

int i;

for(i=0;i

printf("count = %d\n",counter);

sleep(1);

}

return NULL;

}

該進程有兩個線程併發執行,使用同一個全局變量counter,兩個線程都有對counter的訪問權,都可以對其進行訪問。

初始線程每一秒對counter進行加1操作,而新線程每一秒對counter進行一次打印操作。

這樣,我們看一下輸出結果:

線程機制(併發函數的使用)

我們可以看到,兩次輸出有不一樣的結果,原因就在於在新線程對全局變量counter進行打印時,可能初始線程剛剛對counter進行了加1操作,

也可能是剛打印完初始線程才對counter進行了加1操作。這就造成了輸出結果的不確定。

由此我們可以看到,使用全局變量既可進行通信,也同時是一個危險的行為。

五、總結

本文簡單介紹了併發函數的使用,其中涉及了幾個簡單的系統調用。需要注意的是,併發函數使用全局變量既方便,但也危險。本文還未涉及如何安全的對全局變量進行訪問。


分享到:


相關文章: