gpt4 book ai didi

c - 似乎 pthread_create 正在覆盖以前的线程

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:29:12 27 4
gpt4 key购买 nike

我正在尝试编写一个 IRC 类型的聊天客户端,它具有可以连接到服务器的客户端。我试图让它在本地 atm 上工作(使用 FIFOS 而不是套接字)。

我遇到了以下我似乎无法解决的问题:

接受新的客户端连接后,我想为该客户端(在服务器上)创建一个新线程来处理来自该客户端的输入。

为此,我有以下代码(完整代码在底部):

while(1) {
.
.
.
if (pthread_create(&thread, NULL, client_handler, &new_client) != 0)
printf("Couldn't create a thread to listen to the client.... Not ok \n");
}

这适用于 1 个连接的客户端。

当我尝试连接另一个客户端时,似乎执行方法 client_handler 的前一个线程停止运行。我知道这是因为服务器停止接受来自该客户端的输入,但新线程工作正常(处理新连接的客户端的线程)。

我想知道我的方法是否有误,或者我是否没有正确使用 pthread_create。有人有什么建议吗?

void server_listen() {
Client new_client;
ClientNode temp;
buffint client_name_length;
char client_name[CLIENT_NAME_SIZE];
char fifo_in[FIFO_NAME_SIZE], fifo_out[FIFO_NAME_SIZE];
buffint client_pid;
char ack[4] = "/ack";
char inuse[6] = "/inuse";
pthread_t thread;
buffint length;
ClientNode it;
buffint message_length;
char message[MESSAGE_LENGTH];
pthread_mutexattr_t attr;

while (1) {
memset(client_name, 0, CLIENT_NAME_SIZE);
client_name_length.data =0;
if (read_helper(irc_server.server_fifo, client_name_length.buff,
sizeof(int)) == -1)
return; /* error */
if (read_helper(irc_server.server_fifo, client_pid.buff, sizeof(int))
== -1)
return; /* error */
if (read_helper(irc_server.server_fifo, client_name, client_name_length.data) == -1)
return; /* error */

pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_ERRORCHECK_NP);
pthread_mutex_init(&new_client.fifo_in_lock, &attr);

printf("Reading from a new client, with name: %s\n", client_name);
new_client.pid = client_pid.data;
strncpy(new_client.name, client_name, client_name_length.data);
new_client.name_length = client_name_length.data;
sprintf(fifo_in, "fifo-%d-in", client_pid.data);
sprintf(fifo_out, "fifo-%d-out", client_pid.data);
new_client.fifo_in = open(fifo_in, O_WRONLY);
if (new_client.fifo_in == -1)
return; /* error */
new_client.fifo_out = open(fifo_out, O_RDONLY);
if (new_client.fifo_out == -1)
return; /* error */

read_lock();
temp = client_exists_by_name(&irc_server.clients, client_name, client_name_length.data);
read_unlock();

if (temp != NULL) {
pthread_mutex_lock(&new_client.fifo_in_lock);
length.data = 6;
if (write_helper(new_client.fifo_in, length.buff, sizeof(int))
== -1) {
//TODO: What do we do if writing to the fifo_out failed?
printf( "Writing to the fifo-out failed for some unknown reason \n");
return;
}
if (write_helper(new_client.fifo_in, inuse, length.data) == -1) {
//TODO: What do we do if writing to the fifo_out failed?
printf( "Writing to the fifo-out failed for some unknown reason \n");
return;
}
pthread_mutex_unlock(&new_client.fifo_in_lock);
continue;
}


write_lock();
insert_node(&irc_server.clients, new_client);
write_unlock();

length.data = 4;

pthread_mutex_lock(&new_client.fifo_in_lock);
if (write_helper(new_client.fifo_in, length.buff, sizeof(int)) == -1) {
//TODO: What do we do if writing to the fifo_out failed?
printf("Writing to the fifo-out failed for some unknown reason \n");
return;
}
if (write_helper(new_client.fifo_in, ack, length.data) == -1) {
//TODO: What do we do if writing to the fifo_out failed?
printf("Writing to the fifo-out failed for some unknown reason \n");
return;
}
pthread_mutex_unlock(&new_client.fifo_in_lock);


foreach(it, irc_server.clients){
pthread_mutex_lock(&it->client.fifo_in_lock);

strncpy(message, new_client.name, new_client.name_length);
strncat(message, " joined the chat", sizeof(" joined the chat"));
message_length.data = sizeof(" joined the chat") + new_client.name_length;
if (write_helper(it->client.fifo_in, message_length.buff, sizeof(int)) == -1) {
//TODO: What do we do if writing to the fifo_out failed?
printf("writing to the fifo_in a public message ERROR1 \n");
return;
}
if (write_helper(it->client.fifo_in, message, message_length.data) == -1) {
//TODO: What do we do if writing to the fifo_out failed?
printf("writing to the fifo_in a public message ERROR2 \n");
return;
}
pthread_mutex_unlock(&it->client.fifo_in_lock);
memset(message, 0, MESSAGE_LENGTH);
message_length.data = 0;
}

if (pthread_create(&thread, NULL, client_handler, &new_client) != 0)
printf("Couldn't create a thread to listen to the client.... Not ok \n");

if (pthread_create(&thread, NULL,client_handler1 ,&new_client ) != 0)
printf("Couldn't create a thread to listen to the client.... Not ok \n");
print_clients();
}
}

最佳答案

看起来您正在服务器中的所有线程之间共享一个 new_client 实例。调用 pthread_create() 不会神奇地复制 new_client。所以你创建的每个线程都使用相同的 new_client。因此,当您的主线程为第二个客户端填写值时,处理第一个客户端的线程也会尝试使用这些值。

为每个客户端分配一个新的 new_client,填写值并将其传递给 pthread_create()。 pthread_create() 中的第一个参数还需要一个每个客户端变量。

其他 - 您似乎在客户端和服务器之间传递原始二进制数据,例如字符串长度整数。一旦你不得不开始为不同的操作系统做客户端,这种事情就会给你带来一大堆麻烦。我强烈建议您采用序列化技术,最好是 ASN.1(不是免费但非常强大)或 Google Protocol Buffers(免费但不是那么丰富或强大)。

关于c - 似乎 pthread_create 正在覆盖以前的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20849215/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com