cmultithreading

C - local thread variable is shared


I've been trying to pass a variable to threads, but the instant a second thread is created the value changes despite it being created as a constant variable.

//for the first user
if (flag == 0) {
    //store the socket
    cl_sc[0] = client_sock_desc;
    //set id
    whichOne[0] = 0;
    puts("Client accepted");
    //second user ,same procedure
}
else if (flag == 1) {
    cl_sc[1] = client_sock_desc;
    whichOne[0] = 1;
    puts("Client accepted");
}

//create thread and pass cl_sc as argument
pthread_t sTcThread;
pthread_create(&sTcThread, NULL, server_to_client, (void*)whichOne);

And here is the thread implementation

void* server_to_client(void* socket_desc)
{
    // make the argument readable
    const int* whichOne = (int*)socket_desc;

    // one int for retrieved data and one for his socket
    int retrieve, socket = cl_sc[whichOne[0]];

    // chat buddy socket
    int palsSocket;

    // the actual data
    char data[DATA_LENGTH];

    // free the string
    memset(data, 0, DATA_LENGTH);

    for (;;) {
        //set accordingly
        if (whichOne[0] == 0) {
            palsSocket = cl_sc[1];
        }
        else if (whichOne[0] == 1) {
            palsSocket = cl_sc[0];
        }

        printf("Im %d to join my socket is %d and my pals socket is %d\n", whichOne[0], socket, palsSocket);
    }
}

Results of the execution

Client accepted Im 0 to join my socket is 4 and my pals socket is 0
Client accepted Im 1 to join my socket is 5 and my pals socket is 4

But the moment thread 0 is activated this happens

Im 1 to join my socket is 4 and my pals socket is 4

Changing the whichOne constant to 1.

Solved as such thanks to the answers and comments .

    int *whichOneImported = (int *) socket_desc;
    int whichOne = whichOneImported[0];

Solution

  • const int *whichOne = (int *) socket_desc; guarantees that whichOne isn't changed by an instruction of your subroutine, but not by another thread, since it points on a shared memory area (you pass the address to the whichOne array when you create your thread, and you modify its value afterwards when flag == 1)

    you set whichOne[0] = 1; in the other thread, and I'm not sure of the logic but maybe you meant:

    whichOne[flag] = flag;
    

    and then

    pthread_create(&sTcThread, NULL, server_to_client, (void*) (whichOne+flag));
    

    to separate the data

    Or make a allocated copy of whichOne prior to running the thread.