Linux pthread_mutex演示程序
C++語言:
Linux pthread_mutex演示程序Linux 下pthread 中使用mutex 進(jìn)行互斥的程序和結(jié)果
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "pthread.h"
#define THREAD_NUMBER 2
int sum = 0;
void* fun(void* arg) {
int t = (*(int*)arg);
int i;
for (i = t ;i < 10000; i += 2)
sum = sum + i;
return NULL;
}
int main(){
pthread_t T[THREAD_NUMBER];
int arg[THREAD_NUMBER];
int ret,i;
void* join_result;
for (i =0 ;i < THREAD_NUMBER; ++ i){
arg[i] = i;
ret = pthread_create(&T[i],NULL,fun,(void*)&arg[i]);
if (ret){
printf("Thread %d crreate failure!\n",i);
exit(EXIT_FAILURE);
}
}
for (i = 0 ;i < THREAD_NUMBER; ++ i){
ret = pthread_join(T[i],&join_result);
if (ret) {
printf("Thread %d join failure!\n",i);
exit(EXIT_FAILURE);
}
}
printf("sum = %d\n",sum);
return 0;
}
上面的程序是沒有進(jìn)行互斥的 nomutex.c 該程序用于求 1...9999的和,可以gcc -l pthreacd -o test nomutex.c編譯該程序,
并且可以實(shí)驗(yàn)運(yùn)行結(jié)果基本上都是不對的,由于該程序沒有應(yīng)用互斥操作,所以可想而知為什么結(jié)果是不對的。
下面的程序就在上面程序的基礎(chǔ)上加上了求和時(shí)的互斥操作,所以運(yùn)行結(jié)果都是對的。
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "pthread.h"
#define THREAD_NUMBER 2
int sum = 0;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void* fun(void* arg) {
int t = (*(int*)arg);
int i;
for (i = t ;i < 10000; i += 2) {
pthread_mutex_lock(&mutex);
sum = sum + i;
pthread_mutex_unlock(&mutex);
}
return NULL;
}
int main(){
pthread_t T[THREAD_NUMBER];
int arg[THREAD_NUMBER];
int ret,i;
void* join_result;
for (i =0 ;i < THREAD_NUMBER; ++ i){
arg[i] = i;
ret = pthread_create(&T[i],NULL,fun,(void*)&arg[i]);
if (ret){
printf("Thread %d crreate failure!\n",i);
exit(EXIT_FAILURE);
}
}
for (i = 0 ;i < THREAD_NUMBER; ++ i){
ret = pthread_join(T[i],&join_result);
if (ret) {
printf("Thread %d join failure!\n",i);
exit(EXIT_FAILURE);
}
}
printf("sum = %d\n",sum);
return 0;
}
用這兩個(gè)小程序,只是想演示一下linux下pthread 的互斥操作??梢钥吹?,在多線程環(huán)境中,為了保證共享變量的值的正確性,
互斥是非常重要的。
http://fayaa.com/code/view/9949/我覺得應(yīng)該加鎖。理由如下:
比如說有多個(gè)線程都要讀一個(gè)文件。
先要open 打開一個(gè)文件,得到一個(gè)fd
對任一個(gè)讀線程來說操作如下:
1. lseek(fd..)到適當(dāng)?shù)奈恢?div style="height:15px;">
2. read(fd..)
雖然以上每一個(gè)都是原子操作,可是1,2之間是可以中斷的。如果線程一lseek了之后,系統(tǒng)暫時(shí)掛起線程1,運(yùn)行線程二,線程也調(diào)用lseek。
內(nèi)核給每一個(gè)進(jìn)程有一個(gè)進(jìn)程描述結(jié)構(gòu),在Linux中task_struct,在FreeBSD中是proc,存放每一個(gè)進(jìn)程的信息。(下面以FreeBSD為例,因?yàn)閘inux不太清楚,原理應(yīng)該是一樣的).
proc里有一個(gè)struct filedesc,這里存放一個(gè)進(jìn)程所有打開的文件的信息。它里面有一個(gè)struct file的表,每一個(gè)表表示這個(gè)進(jìn)程一個(gè)打開文件。struct file里面記錄了調(diào)用lseek設(shè)定的這個(gè)文件offset大小,對這個(gè)文件的讀寫都是從這里開始的。也就是說這個(gè)offset實(shí)際上是進(jìn)程的各個(gè)線程共享的。
如果出現(xiàn)像上面說的那種情況,線程一設(shè)定的offset就被線程二給修改了。當(dāng)線程一再開始運(yùn)行的時(shí)候,讀到的數(shù)據(jù)肯定是錯(cuò)誤的。
所以說,為了數(shù)據(jù)的正確性,多線程讀一個(gè)文件也應(yīng)該加鎖。