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