简体   繁体   中英

PThread Question

I am trying to make a small thread example. I want to have a variable and each thread try to increment it and then stop once it gets to a certain point. Whenever the variable is locked, I want some sort of message to be printed out like "thread x trying to lock, but cannot" so that I KNOW it's working correctly. This is my first day coding threads so feel free to point out anything unnecessary in the code here -

#include <iostream>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
using namespace std;

#define NUM_THREADS 2
pthread_t threads[NUM_THREADS];
pthread_mutex_t mutexsum;

int NUMBER = 0;
void* increaseByHundred(void* threadid) {

    if(pthread_mutex_lock(&mutexsum))
        cout<<"\nTHREAD "<<(int)threadid<<" TRYING TO LOCK BUT CANNOT";

    else {
        for(int i=0;i<100;i++) {
            NUMBER++;
            cout<<"\nNUMBER: "<<NUMBER;
        }
        pthread_mutex_unlock(&mutexsum);
        pthread_exit((void*)0);
    }
}


int main(int argc, char** argv) {

    int rc;
    int rc1;
    void* status;

    pthread_attr_t attr;

    pthread_mutex_init(&mutexsum, NULL);
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    rc = pthread_create(&threads[0], &attr, increaseByHundred, (void*)0);
    rc1 = pthread_create(&threads[1], &attr, increaseByHundred, (void*)1);

    pthread_attr_destroy(&attr);

    while(NUMBER < 400)
        pthread_join(threads[0], &status);


    pthread_mutex_destroy(&mutexsum);
    pthread_exit(NULL);

}

I was following a tutorial found here https://computing.llnl.gov/tutorials...reatingThreads and tried to adapt their mutex example to this idea. The code increments it up to 199 and then stops. I'm guessing because the threads are only doing their routine once. Is there a way make them just do their routine other than when you create them so I could say

while something do your routine?

I have the pthread_join there just because it was similar to what that tutorial had on theirs. I don't really even get it that clearly though. I'm pretty sure that line is the problem...I just don't know how to fix it. Any help is appreciated.

Whenever the variable is locked, I want some sort of message to be printed out like "thread x trying to lock, but cannot" so that I KNOW it's working correctly.

Why do you want that? You are just learning about threads. Learn the basics first. Don't go diving off the deep end into pthread_mutex_trylock or mutexes configured for error checking. You need to learn to walk before you can learn how to run.

The basics involves a mutex initialized use with default settings and using pthread_mutex_lock to grab the lock. With the default settings, pthread_mutex_lock will only return non-zero if there are big, big problems. There are only two problems that can occur here: Deadlock, and a bad mutex pointer. There is no recovery from either; the only real solution is to fix the code. About the only thing you can do here is to throw an exception that you don't catch, call exit() or abort(), etc.

That some other thread has locked the mutex is not a big problem. It is not a problem at all. pthread_mutex_lock will block (eg, go to sleep) until the lock becomes available. A zero return from pthread_mutex_lock means that the calling thread now has the lock. Just make sure you release the lock when you are done working with the protected memory.

Edit
Here's a suggestion that will let you see that the threading mechanism is working as advertised.

  1. Upon entry to increaseByHundred print a time-stamped message indicating entry to the function. You probably want to use C printf here rather than C++ I/O. printf() and related functions are thread-safe. C++ 2003 I/O is not.
  2. After a successful return from pthread_mutex_lock print another time-stamped message indicating that a successful lock.
  3. sleep() for a few seconds and then print yet another time-stamped message prior to calling pthread_mutex_unlock() .
  4. Do the same before calling pthread_exit() .

One last comment: You are checking for an error return from pthread_mutex_lock . For completeness, and because every good programmer is paranoid as all get out, you should also check the return status from pthread_mutex_unlock .

What about pthread_exit ? It doesn't have a return status. You could print some message after calling pthread_exit , but you will only reach that statement if you are using a non-compliant version of the threads library. The function pthread_exit() cannot return to the calling function. Period. Worrying about what happens when pthreads_exit() returns is a tinfoil hat exercise. While good programmers should be paranoid beyond all get out, they should not be paranoid schizophrenic.

pthread_mutex_trylock():

if (pthread_mutex_trylock(&mutex) == EBUSY) {
    cout << "OMG NO WAY ITS LOCKED" << endl;
}

It is also worth noting that if the mutex is not locked, it will be able to acquire the lock and then it will behave like a regular pthread_mutex_lock() .

pthread_mutex_lock will normally just block until it acquire the lock, and that's why the line cout<<"\nTHREAD "<<(int)threadid<<" TRYING TO LOCK BUT CANNOT"; is not ran. You also have problems in

while(NUMBER < 400)
     pthread_join(threads[0], &status);

because you just have 2 threads and number will never reach 400. You also want to join thread[0] on first iteration, then thread[1]...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM