13 Replies - 504 Views - Last Post: 19 February 2020 - 10:54 AM Rate Topic: -----

#1 jjordan33   User is offline

  • New D.I.C Head

Reputation: -1
  • View blog
  • Posts: 25
  • Joined: 04-February 20

Am I using mutex correctly?

Posted 18 February 2020 - 03:49 PM

Hi, I have a basic withdrawal function I put together from a very beginner understanding of mutex, and I'm not sure if it's right.

pthread_mutex_the_mutex;

void withdraw(void *tid){
	int balance = 70;
	for (int i=0; i<10; i++){
		if (balance < 10)
			pthread_mutex_lock(&the_mutex);

		int readbalance = balance;
		printf("At time %d, the balance for withdrawal thread %d is %d", i, tid, balance);
		readbalance -= 10;
		usleep(1);
		balance = readbalance;
		printf("At time %d, the balance after withdrawal thread %d is %d", i, tid, balance);
		usleep(1);
	}
}




Is This A Good Question/Topic? 0
  • +

Replies To: Am I using mutex correctly?

#2 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7289
  • View blog
  • Posts: 24,666
  • Joined: 05-May 12

Re: Am I using mutex correctly?

Posted 18 February 2020 - 04:19 PM

It looks like you are trying to mix and match techniques to delay taking a lock/mutex. If this is your first go around with mutexes and your profiling for your code is not showing any lock contention, then apply the K.I.S.S. principle. Keep It Simple Stupid. Grab the mutex before you check the balance and potentially change it, then release the mutex.
Was This Post Helpful? 0
  • +
  • -

#3 jjordan33   User is offline

  • New D.I.C Head

Reputation: -1
  • View blog
  • Posts: 25
  • Joined: 04-February 20

Re: Am I using mutex correctly?

Posted 18 February 2020 - 05:10 PM

Like this?

pthread_mutex_the_mutex;
int balance = 100;

void withdraw(void *tid){
	
	for (int i=0; i<10; i++){
		
		pthread_mutex_lock(&the_mutex);
		int readbalance = balance;
		printf("At time %d, the balance for withdrawal thread %d is %d", i, tid, balance);
		readbalance -= 10;
		usleep(1);
		balance = readbalance;
		printf("At time %d, the balance after withdrawal thread %d is %d", i, tid, balance);
		usleep(1);
		pthread_mutex_unlock(&the_mutex);
	}
}


Was This Post Helpful? 0
  • +
  • -

#4 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7289
  • View blog
  • Posts: 24,666
  • Joined: 05-May 12

Re: Am I using mutex correctly?

Posted 18 February 2020 - 05:17 PM

Getting there. Since you have a MUTually EXclusively lock, why do you need the readbalance variable. It isn't like the balance will change under you (unless some cheats and does not respect the lock).

Also, you want to minimize the time you are holding on to lock. Why are you deliberately adding lock time by adding all those sleep calls?
Was This Post Helpful? 0
  • +
  • -

#5 jjordan33   User is offline

  • New D.I.C Head

Reputation: -1
  • View blog
  • Posts: 25
  • Joined: 04-February 20

Re: Am I using mutex correctly?

Posted 18 February 2020 - 05:27 PM

The readbalance and sleeps are part of the skeleton provided. I assume it has something to do with the fact that there will be 2 threads running withdraw, and 2 running a deposit that does the exact same thing as withdraw except adds 11 instead of minus 10.

All 4 working with the global balance variable.
Was This Post Helpful? 0
  • +
  • -

#6 jjordan33   User is offline

  • New D.I.C Head

Reputation: -1
  • View blog
  • Posts: 25
  • Joined: 04-February 20

Re: Am I using mutex correctly?

Posted 18 February 2020 - 06:54 PM

Okay, I made a program. It compiles, but that hardly means anything.

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

int balance = 100;
pthread_t wThread1;
pthread_t wThread2;
pthread_t dThread1;
pthread_t dThread2;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void *p1;
void *p2;
void *p3;
void *p4;

void withdraw(void *tid){

    pthread_mutex_lock(&mutex);
    for (int i=0; i<10; i++){
        int readbalance = balance;
        printf("At time %d, the balance for withdrawal thread %p is %d", i, tid, balance);
        if (readbalance < 10)
            printf("not enough");
        else {
            readbalance -= 10;
            usleep(1);
            balance = readbalance;
            printf("At time %d, the balance after withdrawal thread %p is %d", i, tid, balance);
            usleep(1);
        }
    }
    pthread_mutex_unlock(&mutex);

}

void deposit(void *tid){

    pthread_mutex_lock(&mutex);

    for (int i=0; i<10; i++){
        int readbalance = balance;
        printf("At time %d, the balance before depositing thread %p is %d", i, tid, balance);
        readbalance += 11;
        usleep(10);
        balance = readbalance;
        printf("At time %d, the balance after depositing thread %p is %d", i, tid, balance);
        usleep(10);
    }

    pthread_mutex_unlock(&mutex);

}

int main(){

    pthread_create(&wThread1, NULL, (void *)withdraw, &p1);
    pthread_create(&wThread2, NULL, (void *)withdraw, &p2);
    pthread_create(&dThread1, NULL, (void *)deposit, &p3);
    pthread_create(&dThread2, NULL, (void *)deposit, &p4);

    pthread_join(wThread1, NULL);
    pthread_join(wThread2, NULL);
    pthread_join(dThread1, NULL);
    pthread_join(dThread2, NULL);

}





Was This Post Helpful? 0
  • +
  • -

#7 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7289
  • View blog
  • Posts: 24,666
  • Joined: 05-May 12

Re: Am I using mutex correctly?

Posted 18 February 2020 - 07:04 PM

View Postjjordan33, on 18 February 2020 - 07:27 PM, said:

The readbalance and sleeps are part of the skeleton provided. I assume it has something to do with the fact that there will be 2 threads running withdraw, and 2 running a deposit that does the exact same thing as withdraw except adds 11 instead of minus 10.

I think you need to post the skeleton as well as any specific instructions there are regarding the assignment. The reason I say this is because your code in post #6 will compile and run in a thread safe manner, but it will likely not satisfy the requirements of your homework which probably wants the deposits and withdrawals to interleave. As currently written, post #6 will have each thread eventually gain exclusive control and then loop 10 time doing its deposit or withdrawal, and then let go of the lock and be done.
Was This Post Helpful? 0
  • +
  • -

#8 jjordan33   User is offline

  • New D.I.C Head

Reputation: -1
  • View blog
  • Posts: 25
  • Joined: 04-February 20

Re: Am I using mutex correctly?

Posted 18 February 2020 - 07:14 PM

https://www.utm.edu/...5sp20asmnt3.pdf

I have to read up on how to clean up a thread after it finishes. I have no idea what that means.

Did some reading.
Is that simply pthread_exit(0)?
Was This Post Helpful? 0
  • +
  • -

#9 jjordan33   User is offline

  • New D.I.C Head

Reputation: -1
  • View blog
  • Posts: 25
  • Joined: 04-February 20

Re: Am I using mutex correctly?

Posted 18 February 2020 - 08:19 PM

If I print out the thread with a %d as an int, the number is really high.
Like, 6295792.

Is that right?
Was This Post Helpful? 0
  • +
  • -

#10 jimblumberg   User is offline

  • member icon

Reputation: 5810
  • View blog
  • Posts: 17,740
  • Joined: 25-December 09

Re: Am I using mutex correctly?

Posted 18 February 2020 - 09:01 PM

Also here.
Was This Post Helpful? 1
  • +
  • -

#11 jjordan33   User is offline

  • New D.I.C Head

Reputation: -1
  • View blog
  • Posts: 25
  • Joined: 04-February 20

Re: Am I using mutex correctly?

Posted 18 February 2020 - 09:11 PM

Yeah, and I emailed my professor about it as well. I'll even post on reddit and stackoverflow if I have to.
Was This Post Helpful? -1
  • +
  • -

#12 jjordan33   User is offline

  • New D.I.C Head

Reputation: -1
  • View blog
  • Posts: 25
  • Joined: 04-February 20

Re: Am I using mutex correctly?

Posted 18 February 2020 - 10:11 PM

I have since learned that a thread ID has nothing to do with the number of threads active. It's merely a unique hash given to me.

Disregard.

Thank you.
Was This Post Helpful? 0
  • +
  • -

#13 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7289
  • View blog
  • Posts: 24,666
  • Joined: 05-May 12

Re: Am I using mutex correctly?

Posted 19 February 2020 - 10:43 AM

So the assignment specifically asks for this:

Quote

You should allow maximum currency for all threads

so that means the just grabbing the mutex for the entire thread duration is not going to satisfy the requirements.
Was This Post Helpful? 0
  • +
  • -

#14 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7289
  • View blog
  • Posts: 24,666
  • Joined: 05-May 12

Re: Am I using mutex correctly?

Posted 19 February 2020 - 10:54 AM

So the rules lawyer in me found this bit interesting:

Quote

The following code is part of function withdraw(void *tid) executed by the withdrawal thread (you need to complete it by adding more code on mutex and synchronization if necessary):
:
The following is part of function deposit(void *tid) executed by the depositing thread (you need to complete it by adding more code on mutex and synchronization if necessary):
:


So all that says is that code needs to be in their respective functions. Nothing says that the code necessarily has to be reachable and be executed. I'm quite sure that people will say "Well, it is implied that the code be executed.", but then it is also implied that everybody pay their taxes too, but somehow everybody is taking advantage of everything not covered by the tax rules. :)/>

So at worse you could have code that looks like:
void withdraw(void *tid){
    if (1) {
        /* your code here */
    } else {
        for (int i=0; i<10; i++){
            int readbalance = balance;
            printf("At time %d, the balance for withdrawal thread %p is %d", i, tid, balance);
            readbalance -= 10;
            usleep(1);
            balance = readbalance;
            printf("At time %d, the balance after withdrawal thread %p is %d", i, tid, balance);
            usleep(1);
        }
    }
}

void deposit(void *tid){
    if (1) {
        /* your code here */
    } else {
        for (int i=0; i<10; i++){
            int readbalance = balance;
            printf("At time %d, the balance before depositing thread %p is %d", i, tid, balance);
            readbalance += 11;
            usleep(10);
            balance = readbalance;
            printf("At time %d, the balance after depositing thread %p is %d", i, tid, balance);
            usleep(10);
        }
    }
}



:evil:
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1