连接到不同服务器的线程具有不可预测的结果
Threading to connect to different servers has unpredicatble outcome
我在指定端口有两台服务器 运行。
我正在尝试使用线程并行连接到它们。
当我不使用线程时,代码可以正常工作。
int main(){
// Server 1
char* ip1[]={"127.0.0.1","42069"};
// Server 2
char* ip2[]={"127.0.0.1","42070"};
file_l *file = create_file_l("file.txt",ROOT);
if(file->size != 0)
return -1;
// Common Data Structure that is sent to both threads to prevent overwriting
file_n *filen = create_file_n(file);
filen->part_size = 1024*1024*16;
add_seed(ip1, filen);
add_seed(ip2, filen);
return 1;
}
add_seed
函数连接到给定的服务器并创建一个新线程来处理来自该服务器的数据。
int add_seed(char* ip[], file_n* n){
// Connects to given address and goes file descriptor
int cfd = connectTo(ip);
if(cfd==-1)return -1;
// Data Structure Used to pass parameters to both threads
conn_det *cd = malloc(sizeof *cd);
cd->socket = cfd;cd->file = n;
// Thread Creation
pthread_t temp;
pthread_create(&temp,NULL,initiate_data_transfer,cd);
pthread_detach(temp);
return 1;
}
initiate_data_transfer
函数发送数据请求并处理来自服务器的传入响应。
void* initiate_data_transfer(void *ptr){
printf("Thread ID : %ld\n",syscall(SYS_gettid));
conn_det *cd = ptr;
file_n *n = cd->file;
int socket = cd->socket;int rv=-1;
long size = check_if_available(socket, n->local->name);
printf("Recv Size : %ld Thread ID : %ld\n",size,syscall(SYS_gettid));
// Checks if file size has been set by some other thread
pthread_mutex_lock(&(n->mutex));
if(n->local->size == 0){ // If not , assign file_size
n->local->size = size;
initialize_file_n(n);
}else{
if(n->local->size != size){ // If yes and size from this server does not match, then exit.
pthread_mutex_unlock(&(n->mutex));
return NULL;
}
}
pthread_mutex_unlock(&(n->mutex));
// Data Transfer Part.
printf("Size : %ld Thread ID : %ld\n",n->local->size,syscall(SYS_gettid));
while((rv=get_part(n)) != -1){
printf("Handling Part : %d Thread ID : %ld\n",rv,syscall(SYS_gettid));
send_fetch_request(socket,n,rv);
recv_fetch_response(socket,n,rv);
}
close(socket);
}
用于向线程传递信息的数据结构。
typedef struct File_information_Network{
long part_size;
long total_parts;
int* parts_recieved;
file_l *local;
pthread_mutex_t mutex;
}file_n;
typedef struct Connection_Details
{
int socket;
file_n *file;
}conn_det;
问题是大多数时候只有一个线程到达initiate_data_transfer
函数。
这可以从 initiate_data_transfer
的第一行 printf("Thread ID : %ld\n", syscall(SYS_gettid));
在大多数情况下运行一次而我创建了两个线程这一事实看出。
考虑以下日志:
客户端终端:
user@machine:~/Desktop/cn/FileShare/path$ ./a.out
Connected to: 127.0.0.1
Thread ID : 3164
Connected to: 127.0.0.1
user@machine:~/path$ ./a.out
Connected to: 127.0.0.1
Thread ID : 3169
Connected to: 127.0.0.1
user@machine:~/path$ ./a.out
Connected to: 127.0.0.1
Thread ID : 3174
Connected to: 127.0.0.1
user@machine:~/path$ ./a.out
Connected to: 127.0.0.1
Thread ID : 3179
Connected to: 127.0.0.1
Thread ID : 3180
我不知道出了什么问题,使用 printf
进行调试根本无法帮助我解决问题。感谢任何帮助。
我怀疑主线程只是在两个线程到达 initiate_data_transfer
并开始工作之前就退出了。
尽管您已经分离了新创建的线程,main
线程中的 return 仍将退出进程。
所以代替:
return 1;
从main
开始:
pthread_exit(0);
这将使线程继续运行。当最后一个线程退出时,进程会自动退出。
我在指定端口有两台服务器 运行。
我正在尝试使用线程并行连接到它们。
当我不使用线程时,代码可以正常工作。
int main(){
// Server 1
char* ip1[]={"127.0.0.1","42069"};
// Server 2
char* ip2[]={"127.0.0.1","42070"};
file_l *file = create_file_l("file.txt",ROOT);
if(file->size != 0)
return -1;
// Common Data Structure that is sent to both threads to prevent overwriting
file_n *filen = create_file_n(file);
filen->part_size = 1024*1024*16;
add_seed(ip1, filen);
add_seed(ip2, filen);
return 1;
}
add_seed
函数连接到给定的服务器并创建一个新线程来处理来自该服务器的数据。
int add_seed(char* ip[], file_n* n){
// Connects to given address and goes file descriptor
int cfd = connectTo(ip);
if(cfd==-1)return -1;
// Data Structure Used to pass parameters to both threads
conn_det *cd = malloc(sizeof *cd);
cd->socket = cfd;cd->file = n;
// Thread Creation
pthread_t temp;
pthread_create(&temp,NULL,initiate_data_transfer,cd);
pthread_detach(temp);
return 1;
}
initiate_data_transfer
函数发送数据请求并处理来自服务器的传入响应。
void* initiate_data_transfer(void *ptr){
printf("Thread ID : %ld\n",syscall(SYS_gettid));
conn_det *cd = ptr;
file_n *n = cd->file;
int socket = cd->socket;int rv=-1;
long size = check_if_available(socket, n->local->name);
printf("Recv Size : %ld Thread ID : %ld\n",size,syscall(SYS_gettid));
// Checks if file size has been set by some other thread
pthread_mutex_lock(&(n->mutex));
if(n->local->size == 0){ // If not , assign file_size
n->local->size = size;
initialize_file_n(n);
}else{
if(n->local->size != size){ // If yes and size from this server does not match, then exit.
pthread_mutex_unlock(&(n->mutex));
return NULL;
}
}
pthread_mutex_unlock(&(n->mutex));
// Data Transfer Part.
printf("Size : %ld Thread ID : %ld\n",n->local->size,syscall(SYS_gettid));
while((rv=get_part(n)) != -1){
printf("Handling Part : %d Thread ID : %ld\n",rv,syscall(SYS_gettid));
send_fetch_request(socket,n,rv);
recv_fetch_response(socket,n,rv);
}
close(socket);
}
用于向线程传递信息的数据结构。
typedef struct File_information_Network{
long part_size;
long total_parts;
int* parts_recieved;
file_l *local;
pthread_mutex_t mutex;
}file_n;
typedef struct Connection_Details
{
int socket;
file_n *file;
}conn_det;
问题是大多数时候只有一个线程到达initiate_data_transfer
函数。
这可以从 initiate_data_transfer
的第一行 printf("Thread ID : %ld\n", syscall(SYS_gettid));
在大多数情况下运行一次而我创建了两个线程这一事实看出。
考虑以下日志:
客户端终端:
user@machine:~/Desktop/cn/FileShare/path$ ./a.out
Connected to: 127.0.0.1
Thread ID : 3164
Connected to: 127.0.0.1
user@machine:~/path$ ./a.out
Connected to: 127.0.0.1
Thread ID : 3169
Connected to: 127.0.0.1
user@machine:~/path$ ./a.out
Connected to: 127.0.0.1
Thread ID : 3174
Connected to: 127.0.0.1
user@machine:~/path$ ./a.out
Connected to: 127.0.0.1
Thread ID : 3179
Connected to: 127.0.0.1
Thread ID : 3180
我不知道出了什么问题,使用 printf
进行调试根本无法帮助我解决问题。感谢任何帮助。
我怀疑主线程只是在两个线程到达 initiate_data_transfer
并开始工作之前就退出了。
尽管您已经分离了新创建的线程,main
线程中的 return 仍将退出进程。
所以代替:
return 1;
从main
开始:
pthread_exit(0);
这将使线程继续运行。当最后一个线程退出时,进程会自动退出。