多线程加锁

Linux pthread_mutex演示程序

C++语言:  Linux pthread_mutex演示程序
Linux  pthread  中使用mutex  进行互斥的程序和结果

#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;
}

上面的程序是没有进行互斥的 nomutex.c  该程序用于求  1.. .9999 的和,可以gcc -l pthreacd -o test nomutex.c 编译该程序,
并且可以实验运行结果基本上都是不对的,由于该程序没有应用互斥操作,所以可想而知为什么结果是不对的。

下面的程序就在上面程序的基础上加上了求和时的互斥操作,所以运行结果都是对的。
#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;
}
用这两个小程序,只是想演示一下linux pthread  的互斥操作。可以看到,在多线程环境中,为了保证共享变量的值的正确性,
互斥是非常重要的。

http://fayaa.com/code/view/9949/


我觉得应该加锁。理由如下:
     比如说有多个线程都要读一个文件。
     先要open 打开一个文件,得到一个fd

对任一个读线程来说操作如下:
     1. lseek(fd..)到适当的位置
     2. read(fd..)

虽然以上每一个都是原子操作,可是1,2之间是可以中断的。如果线程一lseek了之后,系统暂时挂起线程1,运行线程二,线程也调用lseek。

内核给每一个进程有一个进程描述结构,在Linux中task_struct,在FreeBSD中是proc,存放每一个进程的信息。(下面以FreeBSD为例,因为linux不太清楚,原理应该是一样的).
proc里有一个struct filedesc,这里存放一个进程所有打开的文件的信息。它里面有一个struct file的表,每一个表表示这个进程一个打开文件。struct file里面记录了调用lseek设定的这个文件offset大小,对这个文件的读写都是从这里开始的。也就是说这个offset实际上是进程的各个线程共享的。
如果出现像上面说的那种情况,线程一设定的offset就被线程二给修改了。当线程一再开始运行的时候,读到的数据肯定是错误的。

所以说,为了数据的正确性,多线程读一个文件也应该加锁。


你可能感兴趣的:(JOIN,thread,多线程,linux,struct,FreeBSD)