文件描述符在线程中重复

文件描述符在线程中重复

我的 C 源代码行为异常。

我使用 Ubuntu 14.04

我用两个pthread

并且在每个 pthread 中调用open ()socket ()

奇怪的是,file descriptor在某些情况下,这种情况会重复发生。

为什么会出现这些症状?

[来源]

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

[输出]

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 !!!!!!!!!!!!!!!!!

答案1

如果你在这两行之间得到上下文切换:

close(fd);
fd=0;

然后旧的 fd 号将可用于套接字号,并且您将得到所看到的内容。

不过,这只是一个较小的问题。代码中较大的问题是您没有使用任何锁定。您的一个线程修改了全局变量,而另一个线程正在使用它们(如果仅在 printf() 调用中)。在没有互斥锁/信号量/临界区/等的情况下这样做是行不通的。

最后 - 编程问题应该在 Stack Overflow 上询问,而不是在这里询问。

相关内容