Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C Unix,pthread_create:自身失败_C_Multithreading_Unix - Fatal编程技术网

C Unix,pthread_create:自身失败

C Unix,pthread_create:自身失败,c,multithreading,unix,C,Multithreading,Unix,我需要帮助。我为我的英语不好道歉。我希望能准确地解释我的问题。 我用C Unix编写了一个客户机/服务器程序。 服务器是多线程的。 在服务器开始操作文件之前,我没有遇到任何问题。 但是要小心,因为真正的问题不在文件操作中:服务器操作文件时没有问题。它可以多次打开和关闭这些文件,并且读写流畅。 真正的问题是:当使用了处理文件的服务的客户机断开自己的连接时,或者当以前的客户机使用了文件处理服务时,新客户机是否希望连接时,服务器接受连接,启动pthread_create函数,但这无法完成新线程的创建。

我需要帮助。我为我的英语不好道歉。我希望能准确地解释我的问题。 我用C Unix编写了一个客户机/服务器程序。 服务器是多线程的。 在服务器开始操作文件之前,我没有遇到任何问题。 但是要小心,因为真正的问题不在文件操作中:服务器操作文件时没有问题。它可以多次打开和关闭这些文件,并且读写流畅。 真正的问题是:当使用了处理文件的服务的客户机断开自己的连接时,或者当以前的客户机使用了文件处理服务时,新客户机是否希望连接时,服务器接受连接,启动pthread_create函数,但这无法完成新线程的创建。然后不执行启动功能。我之所以意识到这种行为,是因为pthread_join返回错误“invalid argument”,我的启动函数没有打印“SERVER:New Thread created!”,同一个pthread_create没有返回错误的“value>0”。 我想澄清的是,当服务器启动时以及启动任意数量的客户端后,一切正常。但一旦一个客户端调用了一个处理文件的服务,服务器就无法完成pthread_create函数。 为什么会这样?我每天都在努力了解发生了什么。谁帮我? 这是创建新线程的函数:

void gestisciConnessioni(int serverfdin, int numeroconnessioniIn, struct sockaddr_in *clientindirizzoin, int *connessioneclientin) {

    //Variabile/i locale/i:
    struct sockaddr *clientindirizzoptr; //Puntatore alla Struttura indirizzo del client
    int clientindirizzodim; //Dimensione dell'indirizzo del client
    char *indirizzoip;
    tipoinfoconnessioneclient *unainfoclient = NULL;
    pthread_t tid;
    int errore = -1;

    //Blocco codice:
    //Il server si mette in ascolto dei clients:

    if ((listen(serverfdin, numeroconnessioniIn)) != 0) {
        printf("SERVER: Attenzione, listening... fallito!\n");
        exit(1);
    }
    //Preparazione indizzamento client:
    clientindirizzoptr = (struct sockaddr *) clientindirizzoin;
    clientindirizzodim = sizeof ((*clientindirizzoin));
    //Inizio concorrenza:
    //Il Server accetta la connessione del client;
    //Verifica la presenza di errori;
    //Inizia l'elaborazione.
    while (1) {
        *connessioneclientin = accept(serverfdin, clientindirizzoptr, &clientindirizzodim);
        if ((*connessioneclientin) > -1) {
            indirizzoip = inet_ntoa((*clientindirizzoin).sin_addr);
            printf("SERVER: Nuova connessione stabilita con %s.\n", indirizzoip);
            unainfoclient = (tipoinfoconnessioneclient *) (malloc(sizeof (tipoinfoconnessioneclient)));
            (*unainfoclient).descrittorefile = *connessioneclientin;
            (*unainfoclient).indirizzoip = indirizzoip;
            errore = pthread_create(&tid, NULL, elaborazioneServizi, (void *) (unainfoclient));
            if (errore != 0) {
                printf("SERVER: Impossibile creare un nuovo thread!\n");
                printf("(SERVER, ERRORE: %s)\n", strerror(errore));
                exit(1);
            }
            pthread_detach(tid);
            errore = pthread_join(tid, NULL);
            if (errore != 0) {
                printf("SERVER: Impossibile attendere la terminazione del thread!\n");
                printf("(SERVER, ERRORE: %s)\n", strerror(errore));
                exit(1);
            }
        } else {
            printf("SERVER: Attenzione, connessione con %s... fallita!\n", indirizzoip);
            exit(1);
        }
    }
}
这是启动功能:

void *elaborazioneServizi(void *args) {

    //Varibile/i locale/i:
    tipoinfoconnessioneclient unainfo;
    tipoinfoutente giocatore;
    int n;
    char messaggioin[100];
    char **messaggioSplittato = NULL;
    int risposta = 0;
    int scelta = -1;
    fd_set insiemelettura;
    int fdmassimo;

    //Blocco codice:
    unainfo = *((tipoinfoconnessioneclient *) args);
    //**************************************************************************
    //Inizializzazione giocatore:
    //**************************************************************************
    giocatore.ip = unainfo.indirizzoip;
    giocatore.nome = " ";
    giocatore.stato = 2;
    giocatore.ultimaposizione.x = -1;
    giocatore.ultimaposizione.y = -1;
    //**************************************************************************
    printf("SERVER: Sto dentro la funzione di avvio!\n");
    fdmassimo = unainfo.descrittorefile;
    FD_SET(unainfo.descrittorefile, &insiemelettura);
    printf("SERVER: Nuovo Thread appena creato!\n");
    select(fdmassimo + 1, &insiemelettura, NULL, NULL, NULL);
    while (risposta == 0) {
        if (FD_ISSET(unainfo.descrittorefile, &insiemelettura)) {
            //*****************************************************************
            if ((n = read(unainfo.descrittorefile, messaggioin, 100)) == -1) {
                printf("SERVER: Errore in ricezione messaggio!\n");
                exit(1);
            }
            while (n == 0) {
                pthread_cond_wait(&condizione, &mutex);
            }
            pthread_cond_signal(&condizione);
            printf("SERVER: Messaggio ricevuto per SWICTH: %s\n", messaggioin);
            messaggioSplittato = messaggioAvettore(messaggioin, 5, 50);
            scelta = atoi(messaggioSplittato[0]);
            switch (scelta) {
                case 0:
                    daiUscita(unainfo.descrittorefile, &risposta);
                    break;
                case 1:
                    daiRegistrazione(unainfo.descrittorefile, messaggioSplittato);
                    break;
                case 2:
                    daiLogin(unainfo.descrittorefile, messaggioSplittato);
                    break;
                default:
                    printf("SERVER: Servizio, non disponibile!\n");
                    risposta = 1;
                    break;
            }
            //*****************************************************************
        }
    }
    printf("SERVER: Thread... eliminato!\n");
    close(unainfo.descrittorefile);
    pthread_exit(NULL);
}
这是执行file.txt(其他文件中最短的)操作的函数:

pthread_创建不外出错误/s。只有错误来自pthread_join 上面写着“无效论点”。我使用一个始终打开的FD(仅限) 然后(每次)关上


您不能加入分离的线程

从man
pthread\u detach

线程一旦被分离,就不能与
pthread\u join
(3)连接,也不能使其再次可连接


您不能加入分离的线程

从man
pthread\u detach

线程一旦被分离,就不能与
pthread\u join
(3)连接,也不能使其再次可连接


仅在调用
pthread\u detach
之后,就不能
pthread\u join
<在线程上执行code>pthread_detach可以确保您不必也不允许
pthread_加入它

创建
pthread\u
,然后紧接着加入
pthread\u
,感觉有点毫无意义。你可以自己调用这个函数,省去你的工作量

这里存在缓冲区溢出:
read(*fd,Messagioletto,dimensionemessaggio)

此处
FD\u集(unainfo.descripttorefile和insiemeletura)未初始化
insi…
变量。说到
select
,现代代码根本不应该使用
select
。特别是当你在线程中时,你一定会期望有很多连接。这意味着您将超出
fd_set
的隐藏限制,该限制通常为1024 fds。改为使用
poll


daiLogin
中锁定一些互斥锁,但在
if(*fd!=-1)时不解锁它{
是错误的。我打赌这就是你认为
pthread\u create
失败的实际原因。
pthread\u create
没有失败,只是你的线程没有打印任何东西,因为互斥锁已经被锁定,
pthread\u join
因为线程被分离而失败。

pthread\u join
调用后你不能
pthread\u join
在线程上执行
pthread\u detach
pthread\u detach
可以确保您不必也不允许
pthread\u加入它

创建
pthread\u
,然后紧接着加入
pthread\u
,感觉有点毫无意义。你可以自己调用函数,省去工作量

这里存在缓冲区溢出:
read(*fd,Messagioletto,dimensionemessaggio)

此处
FD\u集(unainfo.descripttorefile和insiemelettura)
insi…
变量未初始化。说到
select
,现代代码根本不应该使用
select
。特别是因为您正在线程化,这意味着您需要大量连接。这意味着您将超出
fd\u set
的隐藏限制,通常是1024个fd。使用
poll
相反


daiLogin
中锁定一些互斥锁,但在
if(*fd!=-1)时不解锁它{
是错误的。我打赌这就是你认为
pthread\u create
失败的实际原因。
pthread\u create
没有失败,只是你的线程没有打印任何东西,因为互斥锁已经锁定,
pthread\u join
因为线程被分离而失败。

很难解释错误(和帮助)不看产生这些错误的代码!你能用相关的代码更新帖子吗?好的,等一下…我们希望你的代码不会像你的文本那么大1。你不能在调用
pthread\u detach
后就加入
pthread\u detach
pthread\u detach
只做一件事,它确保你的你不必也不能
pthread\u join
它。2.创建
pthread\u
然后紧接着
pthread\u join
感觉有点毫无意义。你可以自己调用函数来省力。3.这里有缓冲区溢出:
read(*fd,messagioletto,dimensionmessaggio)
.4.这里是
FD_集(unainfo.descripttorefile,&insiemelettura);
insi…
变量未初始化。5.现代代码根本不应该使用
select
。特别是因为线程必须意味着需要大量连接。这意味着您将溢出hid
void daiLogin(int canalecomunicazionein, char **messaggioin) {

    //Variabile/i locale/i:
    int dimensionemessaggio = (NICKNAME_DIMENSIONE + PASSWORD_DIMENSIONE) + 2;
    char *nomeutente = NULL;
    char *password = NULL;
    char messaggioletto[NICKNAME_DIMENSIONE + PASSWORD_DIMENSIONE];
    char **messaggiosplittato = NULL;
    char *stringaconvalidata = NULL;
    char *messaggioout = NULL;
    char tmp[3];
    int trovato = 0; //Trovato indica un utente registrato (1) oppure da registrare (0)
    int *fd = NULL;
    int n = -1;

    //Blocco codice:
    pthread_mutex_lock(&mutex);
    printf("SERVER: Sto eseguendo la funzione daiLogin()\n");
    nomeutente = messaggioin[1];
    password = messaggioin[2];
    printf("SERVER: (%s,%s)\n", nomeutente, password);
    fd = inizializzaFileInLettura("registrazioni.txt");
    if (*fd != -1) {
        lseek(*fd, 0, SEEK_SET);
        while ((n = read(*fd, messaggioletto, dimensionemessaggio))&&(trovato == 0)) {
            messaggiosplittato = messaggioAvettore(messaggioletto, 3, dimensionemessaggio);
            if ((strcmp(messaggiosplittato[0], nomeutente) == 0)&&(strcmp(messaggiosplittato[1], password) == 0)) {
                trovato = 1;
            }
            free(messaggiosplittato);
            messaggiosplittato = NULL;
        }
        close(*fd);
        free(fd);
        fd = NULL;
        snprintf(tmp, sizeof (tmp), "%d", trovato);
        messaggioout = componiMessaggio(tmp, "X", "X", "X", "X", 10);
        n = write(canalecomunicazionein, messaggioout, 10);
        pthread_mutex_unlock(&mutex);
    }
}