线程间同步

线程间资源竞争

int count = 0;

void * add(void *arg){
    int val,i;
    for(i = 0;i< 5000;i ++){
        val = count;
        printf("%p: %d\n",pthread_self(),val);
        count = val + 1;
    }
    return nullptr;
}

int main(){
    pthread_t tida,tidb;
    pthread_create(&tida,NULL,add,NULL);
    pthread_create(&tidb,NULL,add,NULL);

    pthread_join(tida,NULL);
    pthread_join(tidb,NULL);
    return 0;
}

两个线程同时跑,最后的结果是4999,并不是我们想象中的10000。这是为什么呢?多个线程访问和修改了全局变量count,而这个变量没有被任何同步机制保护。在并发执行的情况下,多个线程可能会同时读取和修改count变量的值,从而导致竞态条件的发生。具体来说,当两个线程同时读取count变量的值并保存到本地变量中时,它们得到的可能是相同的值。接着两个线程分别将本地变量加1,并写回到count变量中。这样就会出现一个线程的修改被覆盖的情况,导致最终结果小于预期值。

因此,为了避免竞态条件,需要使用同步机制来保护多个线程对共享资源的访问,例如使用互斥锁、信号量等机制。这些同步机制可以确保每次只有一个线程能够访问和修改共享资源,从而避免多个线程同时修改同一个资源的情况,从而保证程序的正确性和可预测性。

线程间同步

对于多线程的程序,访问冲突是很普遍的,解决方法是引入互斥锁(MUtex,MutualExclusive Lock),获得锁的线程可以完成”读-修改-写“的操作,然后释放锁给其他的线程,没有获得所得线程只能等待而不能访问共享数据,这样”读-修改-写"三步操作组成一个原子操作,要么都执行,要么都不执行,不会执行到中间被打断,也不会在其他处理器上并行做这个操作

int count = 0;

pthread_mutex_t add_mux = PTHREAD_MUTEX_INITIALIZER;

void * add(void *arg){
    int val,i;
    for(i = 0;i< 5000;i ++){
        pthread_mutex_lock(&add_mux);
        val = count;
        printf("%p: %d\n",pthread_self(),val);
        count = val + 1;
        pthread_mutex_unlock(&add_mux);
    }
    return nullptr;
}

int main(){
    pthread_t tida,tidb;
    pthread_create(&tida,NULL,add,NULL);
    pthread_create(&tidb,NULL,add,NULL);

    pthread_join(tida,NULL);
    pthread_join(tidb,NULL);
    return 0;
}

条件变量

线程间同步_第1张图片

生产者消费者模型

typedef struct Goods {
    int data;
    struct Goods *next;
} Goods;

Goods *head = NULL;
pthread_mutex_t mutex_head = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t have_good_cond = PTHREAD_COND_INITIALIZER;

void *producer(void *) {
    Goods *newGood;
    while (1) {
        newGood = (Goods *) malloc(sizeof(Goods));
        newGood->data = rand() % 100;
        // 头插法
        pthread_mutex_lock(&mutex_head);
        newGood->next = head;
        head = newGood;
        pthread_mutex_unlock(&mutex_head);
        pthread_cond_signal(&have_good_cond);
        printf("produce %d\n", newGood->data);
        sleep(rand() % 3);
    }
}

void *consumer(void *) {
    Goods *k;
    while (1) {
        pthread_mutex_lock(&mutex_head);
        if (!head) {
            pthread_cond_wait(&have_good_cond, &mutex_head);
        }
        k = head;
        head = head->next;
        pthread_mutex_unlock(&mutex_head);
        printf("consume %d\n", k->data);
        free(k);
        sleep(rand() % 3);
    }
}

pthread_t produceThread, consumerThread;

int main() {
    srand(time(nullptr));

    pthread_create(&produceThread, nullptr, producer, nullptr);
    pthread_create(&consumerThread, nullptr, consumer, nullptr);

    pthread_join(produceThread, NULL);
    pthread_join(consumerThread, NULL);
    return 0;
}

你可能感兴趣的:(计算机操作系统,java,c++,算法)