用于RaceCondition控件的Pthreads和Mutexes

时间:2017-11-06 05:49:28

标签: c pthreads

我遇到的问题是我的代码没有获取所需的互斥锁以管理竞争条件。该代码故意通过使用nanosleep暂停线程并让它们竞争相同的数据来引起竞争条件。我的问题是,当在代码中添加互斥锁时,并非所有线程都在执行,因此给出了错误的值。

#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <time.h>
#include <sys/time.h>

#define NUM_THREADS 10

//Global Value
int SHARED_VALUE = 0 ;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

void* add10(void*);
struct timespec ts = {0, 10};


int main() {
    //Required for thread creation
    pthread_t thread_id; //Thread Identifier
    pthread_attr_t attributes; //Default Attributes
    pthread_attr_init(&attributes); //Attributes Initialized to Default            Values

    //Initialize Mutex
    if (pthread_mutex_init(&lock, NULL) != 0){
        fprintf(stderr,"Error Creating Mutex\n");
        return -100;
    }
    //Spawn 10 Threads
    for(int i = 0; i < NUM_THREADS;i++){

        thread_id = i+1;

    if(pthread_create(&thread_id,&attributes,add10,thread_id) != 0) {
            fprintf(stderr,"Error Creating Thread: %d", thread_id);
            return -100;
    }
 }


for(int i = 0; i < NUM_THREADS; i++){
    pthread_join (thread_id,NULL);
}

//pthread_mutex_destroy(&lock);

printf("Shared_Value: %d", SHARED_VALUE);

}

void* add10(void* arg) {
    int thread_id = (int *) arg;
    if ((pthread_mutex_lock(&lock)) == 0) {
        fprintf(stderr, "Lock Acquired:%d\n", (int *) arg);
        //Access Shared Value
        int local_value = SHARED_VALUE;
        fprintf(stderr, "\tInitial Local Value: %d\n", local_value);
        local_value = local_value + 10;
        fprintf(stderr, "\tPost Local Value: %d\n", local_value);
        //Stall thread for race conditions
        nanosleep(&ts, NULL);
        SHARED_VALUE = local_value;
    } else {
        fprintf(stderr, "No Lock!\n");
        pthread_exit;
    }
    if ((pthread_mutex_unlock(&lock)) < 0) {
        fprintf(stderr, "Error on unlock\n");
    }
}

输出看起来像:

Lock Acquired:5
    Initial Local Value: 0
    Post Local Value: 10
Lock Acquired:6
    Initial Local Value: 10
    Post Local Value: 20
Lock Acquired:4
    Initial Local Value: 20
    Post Local Value: 30
Lock Acquired:7
    Initial Local Value: 30
    Post Local Value: 40
Lock Acquired:9
    Initial Local Value: 40
    Post Local Value: 50
Lock Acquired:10
    Initial Local Value: 50
    Post Local Value: 60
Shared_Value: 60Lock Acquired:8

Process finished with exit code 0

2 个答案:

答案 0 :(得分:1)

for(int i = 0; i < NUM_THREADS;i++){
        thread_id = i+1;
    if(pthread_create(&thread_id,&attributes,add10,thread_id) != 0)

您对所有线程使用相同的变量thread_id。您需要一个数组。

pthread_t thread_id[10];
for(int i = 0; i < NUM_THREADS;i++){
    if(pthread_create(&thread_id[i],&attributes,add10,thread_id[i]) != 0)

答案 1 :(得分:1)

好吧,基本上你只是等待一个线程加入并忽略剩余的9个线程

   for(int i = 0; i < NUM_THREADS; i++){
            pthread_join (thread_id,NULL);
    }

因为这个创建语句

 if(pthread_create(&thread_id,&attributes,add10,thread_id) != 0)