线程同步

线程的主要优势在于,能够通过全局变量来共享信息。必须确保多个线程不会同时修改同一变量,或者某一线程不会读取正由

其他线程修改的变量。临界区是指访问某一共享资源的代码片段,并且这段代码的执行应为原子操作,亦即,同时访问同一共享

资源的其他线程不应中断该片段的执行。可以使用互斥量来保证对任意共享资源的原子访问,而保护共享变量是其最常见的用法。

每一线程在访问同一资源时将采用如下协议:

    1)针对共享资源锁定互斥量

    2)访问共享资源

    3)对互斥量解锁

避免死锁,最简单的方法是定义互斥量的层级关系。当多个线程对一组互斥量操作时,总是应该以相同顺序对该组互斥量进行锁定。

互斥量防止多个线程同时访问同一共享变量。条件变量允许一个线程就某个共享变量(或其他共享资源)的状态变化通知其他线程,

并让其他线程等待(阻塞于)这一通知。

导致线程不安全的典型原因:使用了在所有线程之间共享的全局或静态变量。

实现线程安全的方式多样,其一是将函数与互斥量关联使用,在调用函数时将其锁定,在函数返回时解锁。

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

static int glob=0;
static pthread_mutex_t mtx=PTHREAD_MUTEX_INITIALIZER;

static void * threadFunc(void *arg) {
    int loops = *((int *)arg);
    int loc, j, s;

    for(j=0; j<loops; j++) {
        s = pthread_mutex_lock(&mtx);
        if(s != 0) {
            fprintf(stderr, "pthread_mutex_lock error.");
            return (void *)-1;
        }
        loc = glob;
        loc++;
        glob = loc;

        s = pthread_mutex_unlock(&mtx);
        if(s != 0) {
            fprintf(stderr, "pthread_mutex_unlock error.");
            return (void *)-1;
        }
    }

    return NULL;
}

int main() {
    pthread_t t1, t2;
    int loops, s;

    printf("Input the loops: ");
    scanf("%d", &loops);

    s = pthread_create(&t1, NULL, threadFunc, &loops);
    if(s != 0) {
        fprintf(stderr, "pthread_create error.");
        return -1;
    }

    s = pthread_create(&t2, NULL, threadFunc, &loops);
    if(s != 0) {
        fprintf(stderr, "pthread_create error.");
        return -1;
    }

    s = pthread_join(t1, NULL);
    if(s != 0) {
        fprintf(stderr, "pthread_join error.");
        return -1;
    }

    s = pthread_join(t2, NULL);
    if(s != 0) {
        fprintf(stderr, "pthread_join error.");
        return -1;
    }

    printf("glob = %d
", glob);

    return 0;
}
原文地址:https://www.cnblogs.com/donggongdechen/p/15013921.html