O descritor de arquivo é duplicado no encadeamento [fechado]

0

Minha fonte C se comporta de maneira estranha.

Eu uso o Ubuntu 14.04

Eu uso dois pthread .

E em cada uma das chamadas pthread, o open () e socket () .

Curiosamente, este file descriptor é duplicado em certos casos.

Por que esses sintomas aparecem?

[fonte]

#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;
}

[Saída]

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 !!!!!!!!!!!!!!!!!
    
por DonBit 10.12.2015 / 06:21

1 resposta

1

Se você tiver uma alternância de contexto entre essas duas linhas:

close(fd);
fd=0;

Então o antigo número fd estará disponível para um número de socket e você obterá o que vê.

Este é o problema menor. O maior problema no seu código é que você não usa nenhum bloqueio. Um de seu segmento modifica variáveis globais e o outro está usando-as (se apenas em chamadas printf ()). Fazer isso sem mutexes / semafors / seções críticas / etc não vai funcionar.

E finalmente - questões de programação devem ser feitas no estouro da pilha, não aqui.

    
por sмurf 10.12.2015 / 07:22

Tags