请考虑以下代码:
void* echo_data(void* client_socket) {
// for the sake of argument - suppose there's a lot of code here before we copy the socket to local variable:
int socket = *(int*)client_socket;
// send back whatever is coming from client
return (void*)0;
}
int main(int argc, char* argv[]) {
int server_socket = establish_connection();
while (1) {
int incoming_client_socket = wait_for_connection(server_socket);
fprintf(stdout, "new connection accepted...\n");
pthread_t client_thread;
pthread_create(&client_thread, NULL, echo_data, (void*)&incoming_client_socket);
}
}
我知道我在这里忽略了返回代码,但是这段代码实际上没有运行(没有establish_connection
或wait_for_connection
)并且汇总在一起传达一个想法,所以为了论证,我们说所有的功能总是成功的...
但是,我确实特别想知道使用局部变量作为新创建线程的参数的含义
请考虑以下情形:
wait_for_connection
接受新连接并返回incoming_client_socket
。incoming_client_socket
通过"参考"到新创建的帖子中的echo_data
,当前它存储在main()
卡住了。echo_data
复制client_socket
指向的数据需要一些时间,同时主线程接受另一个连接,这将超出之前的incoming_client_socket
- 然后该线程会复制错误的数据。这真的是一个问题吗? 如果没有,怎么样? 如果是这样,那么这样做是否安全?
答案 0 :(得分:2)
这真的是一个问题吗?
是。它不是一种安全的方式。
您可以直接传递值,而不是传递其地址。
pthread_create(&client_thread, NULL, echo_data, (void*) incoming_client_socket);`
并且线程函数应该像
void* echo_data(void* client_socket) {
int socket = (int)client_socket;
/* your code */
}
如果你希望将多个元素传递给线程,那么你可以将它包装在一个结构中,为它创建一个结构指针,分配内存并填充值并将指针传递给线程。
struct X {
int socket;
/* other members here*/
};
和
while (1) {
int incoming_client_socket = wait_for_connection(server_socket);
fprintf(stdout, "new connection accepted...\n");
struct X *ptr = malloc (sizeof(struct X));
ptr->socket = incoming_client_socket;
/* other assignment here */
pthread_create(&client_thread, NULL, echo_data, (void*)ptr);
}
你的线程函数应该看起来像
void* echo_data(void* client_socket) {
// for the sake of argument - suppose there's a lot of code here before we copy the socket to local variable:
struct X *ptr = (struct X *)client_socket;
// send back whatever is coming from client
return (void*)0;
}
不要忘记释放记忆。