0

My C source behaves strangely.

I use Ubuntu 14.04

I use two pthread.

And in each of pthread calls the open () and socket ().

Oddly, this file descriptor is duplicated in certain cases.

Why do these symptoms appear?

[Source]

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/types.h> 
#include <sys/socket.h> 
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <math.h>
#include <asm/types.h>
#define NUM_THREADS 1

int server_socket=0;
int fd=0;


void* socket_open(void *t)
{
    int i;
    long tid;
    double result=0.0;

    printf("%s() thread tart\n",__func__);

    for (i = 0; i < 10000; i++)
    {


        server_socket  = socket( PF_INET, SOCK_STREAM, 0);
        if( -1 == server_socket)
        {
          printf( "server socket failed\n");
          exit( 1);
        }

        if(server_socket == fd){
            printf("%s() server_socket=%d fd=%d !!!!!!!!!!!!!!!!!!!!!!!!\n",__func__,server_socket, fd);

        }

        close(server_socket);
        server_socket=0;


    }

    pthread_exit((void*) t);
}

void*
file_open(void *t)
{
    int i;
    long tid;
    double result=0.0;


    printf("%s() thread tart\n",__func__);

    for (i = 0; i < 10000; i++)
    {

        fd = open("/dev/null", O_RDWR);
        if( -1 == fd)
        {
          printf( "server socket failed\n");
          exit( 1);
        }


        if(server_socket == fd){
            printf("%s() server_socket=%d fd=%d !!!!!!!!!!!!!!!!!!!!!!!!\n",__func__,server_socket, fd);

        }        

        close(fd);
        fd=0;


    }

    pthread_exit((void*) t);
}

void* 
PthreadCreate(void* arg)
{
    pthread_t thread[NUM_THREADS];
    pthread_attr_t attr;
    int rc;
    long t;
    void *status;

    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    for(t = 0; t < NUM_THREADS; t++) 
    {

        rc = pthread_create(&thread[t], &attr, socket_open, (void *)t); 
        if (rc) 
        {
            printf("ERROR; return code from pthread_create() is %d\n", rc);
            return NULL;
        }
    }

    pthread_attr_destroy(&attr);
    for(t = 0; t < NUM_THREADS; t++) 
    {
        rc = pthread_join(thread[t], &status);
        if (rc) 
        {
            printf("ERROR; return code from pthread_join() is %d\n", rc);
            return NULL;
        }

    }


    pthread_exit(NULL);
}

void* 
PthreadCreate1(void* arg)
{
    pthread_t thread[NUM_THREADS];
    pthread_attr_t attr;
    int rc;
    long t;
    void *status;


    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    for(t = 0; t < NUM_THREADS; t++) 
    {

        rc = pthread_create(&thread[t], &attr, file_open, (void *)t); 
        if (rc) 
        {
            printf("ERROR; return code from pthread_create() is %d\n", rc);
            return NULL;
        }
    }
     pthread_attr_destroy(&attr);
    for(t = 0; t < NUM_THREADS; t++) 
    {
        rc = pthread_join(thread[t], &status);
        if (rc) 
        {
            printf("ERROR; return code from pthread_join() is %d\n", rc);
            return NULL;
        }
    }


    pthread_exit(NULL);
}

int
main(void)
{
    pthread_t mainThread;
    pthread_t mainThread1;

    pthread_create(&mainThread, NULL, PthreadCreate, NULL);
    pthread_create(&mainThread1, NULL, PthreadCreate1, NULL);
    pthread_exit(NULL);
    return 0;
}

[Output]

socket_open() server_socket=3 fd=3 !!!!!!!!!!!!!!!!!
socket_open() server_socket=3 fd=0 !!!!!!!!!!!!!!!!!
socket_open() server_socket=3 fd=0 !!!!!!!!!!!!!!!!!
socket_open() server_socket=3 fd=0 !!!!!!!!!!!!!!!!!
socket_open() server_socket=3 fd=0 !!!!!!!!!!!!!!!!!
file_open() server_socket=3 fd=3 !!!!!!!!!!!!!!
file_open() server_socket=3 fd=3 !!!!!!!!!!!!!!
socket_open() server_socket=3 fd=0 !!!!!!!!!!!!!!!!!
socket_open() server_socket=3 fd=3 !!!!!!!!!!!!!!!!!
socket_open() server_socket=3 fd=3 !!!!!!!!!!!!!!!!!
socket_open() server_socket=3 fd=3 !!!!!!!!!!!!!!!!!
socket_open() server_socket=3 fd=3 !!!!!!!!!!!!!!!!!
socket_open() server_socket=3 fd=3 !!!!!!!!!!!!!!!!!
socket_open() server_socket=3 fd=3 !!!!!!!!!!!!!!!!!
socket_open() server_socket=3 fd=0 !!!!!!!!!!!!!!!!!
socket_open() server_socket=3 fd=0 !!!!!!!!!!!!!!!!!
socket_open() server_socket=3 fd=0 !!!!!!!!!!!!!!!!!
socket_open() server_socket=3 fd=3 !!!!!!!!!!!!!!!!!
David Foerster
  • 36,264
  • 56
  • 94
  • 147
DonBit
  • 129
  • 1
  • 9

1 Answers1

1

If you get a context switch between these 2 lines:

close(fd);
fd=0;

Then the old fd number will be available for a socket number and you will get what you see.

This is the smaller problem though. The bigger problem in your code is that you do not use any locking. One of your thread modifies global variables and the other is using them (if only in printf() calls). Doing that without mutexes / semafors / critical sections / etc is not going to work.

And finally - programming questions ought to be asked on stack overflow, not here.

sмurf
  • 4,680