У меня есть два сервера, работающих на указанных портах.
Я пытаюсь подключиться к ним обоим параллельно, используя потоки.
Код работает, как требуется, когда я не многопоточен.
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 = 102416;
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
большую часть времени.
Это видно из того факта, что printf("Thread ID : %ld\n", syscall(SYS_gettid));
, который является первой строкой initiate_data_transfer
, запускается один раз в большинстве случаев, тогда как я создал два потока. *1024*
Рассмотрим следующие журналы:
Терминал Клиента:
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
для отладки не помогает мне понять это совсем. Любая помощь приветствуется.