访问结构指针作为 pthread arg 会导致段错误?
Accessing struct pointer as pthread arg causes seg fault?
所以这是我的一小部分代码。本质上我是从一个方法启动另一个线程,但是当我将整数传递给 pthread 时,我无法访问结构成员,就像在调用线程之前我只能访问两行一样。自从我通过这个论点和 运行 一个新线程后发生了什么?
请注意,我的程序总是在 printf("1\n"); 之后立即崩溃,我在意识到 FD_ZERO 时发现了这个错误没用。
结构定义(在全局区域):
typedef struct {
fd_set read_set, write_set;
unsigned int room_id;
char room_name[16];
} room;
调用方法:
void create_new_room(int cli_index, char buffer[]) {
pthread_mutex_lock(&mutex);
char room_name[16], password[16];
int capacity, r_index;
room *new_room = malloc(sizeof(room));
pthread_t tid;
FILE *room_file = NULL;
if((room_file = fopen("room-info.txt", "a")) == NULL) {
perror("Failed to open file.");
exit(-1);
}
// Split command data into separate strings ready to assign as room struct members
strtok(buffer, " ");
strcpy(room_name, strtok(NULL, " "));
capacity = atoi(strtok(NULL, " "));
strcpy(password, strtok(NULL, " "));
// Initialise room struct
// --Zero write set
FD_ZERO(&(new_room->write_set));
// --Set room name
strcpy(new_room->room_name, room_name);
// --Set room id
new_room->room_id = ++natural_id;
// --Add room to room_list[] and get its index in the array
for(r_index = 0; r_index < 10000; ++r_index) {
if(!room_list[r_index]) {
room_list[r_index] = new_room;
break;
}
}
// Write data to file
fprintf(room_file, "%s\n", room_name);
fprintf(room_file, "id=%u\n", natural_id);
fprintf(room_file, "owner=%s\n", client_list[cli_index]->name);
fprintf(room_file, "capacity=%d\n", capacity);
fclose(room_file);
printf("about to test\n");
printf("Testing room struct:\n");
printf("--room name = %s\n", room_list[r_index]->room_name);
printf("--room id = %u\n", room_list[r_index]->room_id);
printf("post-test.....................\n");
// Run new thread as active room
printf("Starting new room: %s\n", room_name);
pthread_create(&tid, NULL, (void *) &active_room, &r_index);
pthread_mutex_unlock(&mutex);
}
开始新的 pthread 方法:
void active_room(void *index) {
char storage_buffer[BSIZE], output_buffer[BSIZE+32];
struct timeval timeout;
int r_index = *(int *) index;
while(1) {
// debugging lines.
printf("1\n");
printf("room name: %s\n", room_list[r_index]->room_name);
printf("room id: %u\n", room_list[r_index]->room_id);
FD_ZERO(&(room_list[r_index]->read_set));
read_set = write_set;
timeout.tv_sec = 5;
printf("2\n");
create_new_room
中的 r_index
变量是函数的局部变量。然后将它的地址传递给 pthread_create
以便线程可以使用它,但随后 create_new_room
退出,导致 r_index
的生命周期结束。然后当线程试图取消引用它的参数时,它指向不再有效的内存,触发 undefined behavior.
您需要为线程的参数动态分配内存,以便它在 create_new_room
退出后继续存在:
int *r_index_arg = malloc(sizeof *r_index_arg);
*r_index_arg = r_index;
pthread_create(&tid, NULL, (void *) &active_room, r_index_arg);
然后你需要确保你free
线程中的内存:
int r_index = *(int *) index;
free(index);
所以这是我的一小部分代码。本质上我是从一个方法启动另一个线程,但是当我将整数传递给 pthread 时,我无法访问结构成员,就像在调用线程之前我只能访问两行一样。自从我通过这个论点和 运行 一个新线程后发生了什么?
请注意,我的程序总是在 printf("1\n"); 之后立即崩溃,我在意识到 FD_ZERO 时发现了这个错误没用。
结构定义(在全局区域):
typedef struct {
fd_set read_set, write_set;
unsigned int room_id;
char room_name[16];
} room;
调用方法:
void create_new_room(int cli_index, char buffer[]) {
pthread_mutex_lock(&mutex);
char room_name[16], password[16];
int capacity, r_index;
room *new_room = malloc(sizeof(room));
pthread_t tid;
FILE *room_file = NULL;
if((room_file = fopen("room-info.txt", "a")) == NULL) {
perror("Failed to open file.");
exit(-1);
}
// Split command data into separate strings ready to assign as room struct members
strtok(buffer, " ");
strcpy(room_name, strtok(NULL, " "));
capacity = atoi(strtok(NULL, " "));
strcpy(password, strtok(NULL, " "));
// Initialise room struct
// --Zero write set
FD_ZERO(&(new_room->write_set));
// --Set room name
strcpy(new_room->room_name, room_name);
// --Set room id
new_room->room_id = ++natural_id;
// --Add room to room_list[] and get its index in the array
for(r_index = 0; r_index < 10000; ++r_index) {
if(!room_list[r_index]) {
room_list[r_index] = new_room;
break;
}
}
// Write data to file
fprintf(room_file, "%s\n", room_name);
fprintf(room_file, "id=%u\n", natural_id);
fprintf(room_file, "owner=%s\n", client_list[cli_index]->name);
fprintf(room_file, "capacity=%d\n", capacity);
fclose(room_file);
printf("about to test\n");
printf("Testing room struct:\n");
printf("--room name = %s\n", room_list[r_index]->room_name);
printf("--room id = %u\n", room_list[r_index]->room_id);
printf("post-test.....................\n");
// Run new thread as active room
printf("Starting new room: %s\n", room_name);
pthread_create(&tid, NULL, (void *) &active_room, &r_index);
pthread_mutex_unlock(&mutex);
}
开始新的 pthread 方法:
void active_room(void *index) {
char storage_buffer[BSIZE], output_buffer[BSIZE+32];
struct timeval timeout;
int r_index = *(int *) index;
while(1) {
// debugging lines.
printf("1\n");
printf("room name: %s\n", room_list[r_index]->room_name);
printf("room id: %u\n", room_list[r_index]->room_id);
FD_ZERO(&(room_list[r_index]->read_set));
read_set = write_set;
timeout.tv_sec = 5;
printf("2\n");
create_new_room
中的 r_index
变量是函数的局部变量。然后将它的地址传递给 pthread_create
以便线程可以使用它,但随后 create_new_room
退出,导致 r_index
的生命周期结束。然后当线程试图取消引用它的参数时,它指向不再有效的内存,触发 undefined behavior.
您需要为线程的参数动态分配内存,以便它在 create_new_room
退出后继续存在:
int *r_index_arg = malloc(sizeof *r_index_arg);
*r_index_arg = r_index;
pthread_create(&tid, NULL, (void *) &active_room, r_index_arg);
然后你需要确保你free
线程中的内存:
int r_index = *(int *) index;
free(index);