2016-12-13 7 views
0

Я новый в теме в c. Мой код имеет поток, который увеличивает счетчик, а иногда (случайно) другой поток считывает этот счетчик. Я использовал мьютекс в этом коде, но мой код всегда дает мне значение, равное 1. Хотя я использовал pthread_mutex_unlock, но кажется, что значение становится заблокированным навсегда. что я должен сделать, чтобы решить эту проблему?Мьютекс фиксирует значение в функции навсегда

#include <unistd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <sys/fcntl.h> 
#include <pthread.h> 
/////////////////////////// 

long int count=0; 
int RunFlag=0; 
pthread_mutex_t mtx; 

void *readfun(void *arg) 
{ 
    while (RunFlag==0) 
    { 
     pthread_mutex_lock(&mtx); 
     count=count+1; 
     pthread_mutex_unlock(&mtx); 
    } 

} 
void *printfun(void *arg) 
{ 
    int RadnTime=0; 
    for (int j=0;j<4;j++) 
    { 
     RadnTime=rand()%3+1; 
     sleep(RadnTime); 

     printf("The current counter after %d seconds is: ",RadnTime); 
     pthread_mutex_lock(&mtx); 
     printf("%d\n",count); 
     pthread_mutex_unlock(&mtx); 
    } 



} 

void main() 
{ 
    pthread_t thread1; 
    pthread_t thread2; 

    pthread_mutex_init(&mtx, NULL); 

    pthread_create(&thread1,NULL,readfun,NULL); 
    pthread_create(&thread2,NULL,printfun,NULL); 

    //stop the counter 
    RunFlag=1; 

    pthread_exit(NULL); 
} 

ответ

1

Вы устанавливаете RunFlag сразу после того, как созданы два потока, так readfun едва имеет любое время для выполнения. RunFlag=1; должен быть в конце printfun.


Насколько я знаю, чтение и запись RunFlag не гарантируется атомарным, поэтому доступ к нему должен быть защищен, а также. Я не вижу здесь проблемы (учитывая значения, о которых идет речь), но вы входите в неопределенную территорию поведения.


Ваши функции ничего, даже если они объявлены как возвращение void* не возвращаются. Добавьте return NULL; к ним.


Наконец, второй %d должно быть %ld, поскольку count является long int.


Обратите внимание, что

pthread_mutex_t mtx; 
pthread_mutex_init(&mtx, NULL); 

можно заменить

pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER; 
+0

Это приведет к тому, что данные гонки пройдут. – 2501

+1

Конечно, есть. RunFlag записывается в один поток, будучи прочитанным в другом, без защиты. – 2501

+0

Вы правы. Я сейчас работаю, огромное спасибо :) –

1

1) Вы также data race как два имеют доступ к RunFlag. Таким образом, вам необходимо защитить его с помощью примитива синхронизации (например, мьютекса или семафора).

Для этой цели вам не нужен RunFlag. Так как вы можете использовать бесконечный цикл в потоке readfun(), а затем просто вызываете _exit() из printfun() нить, чтобы выйти из всего процесса.

2) Функции резьбы должны возвращать указатель, удовлетворяющий требованиям pthread_create(). Но функции потока ничего не возвращают. Вы можете добавить return NULL; в конце обеих функций потока.

Знайте, что signed integer overflow как count может потенциально переполняться.