gpt4 book ai didi

multithreading - C 套接字编程中使用链表的线程安全

转载 作者:行者123 更新时间:2023-12-03 11:53:09 25 4
gpt4 key购买 nike

我正在使用线程和 TCP 在 C 中实现 P2P 文件传输。我有一个跟踪器,它跟踪所有连接到它的对等点。当对等方首次连接时,它将其文件从其当前目录发送到跟踪器,跟踪器将所有对等方的文件放入共享链表中。每个对等点在跟踪器中都有自己的线程,当对等点退出时,跟踪器关闭该对等点的连接并从链表中删除该对等点的所有文件。我关心的是在添加和删除节点时锁定链表。我希望能够安全地从各种线程更改链表。我已经编写了我的代码以从我的链表中添加/删除以及搜索(不确定我在搜索时是否需要使用锁定)我如何修改我的代码以确保线程之间的链接安全?

最佳答案

请考虑使用互斥锁来保护数据或其他资源免受并发访问。

在 POSIX 线程的上下文中,pthread_mutex_t 类型(来自 sys/types.h, The Open Group Base Specifications Issue 7, IEEE Std 1003.1, 2013 Edition)用于互斥量。

pthread_mutex_lock()pthread_mutex_unlock() 函数 ( The Open Group Base Specifications Issue 7, IEEE Std 1003.1, 2013 Edition ) 可用于保护链表类型的实例免受两个操作的并发访问:

  • 读操作:当枚举列表(即读取next指针)和使用(读/写)存储在节点中的数据时;
  • 写操作:更改节点:next 指针和存储在节点中的数据。

此外,相同的互斥体可用于保护对head [of the linked-list] 指针的访问。

例子:

// ...

pthread_mutex_t list_mutex = PTHREAD_MUTEX_INITIALIZER;

// ...

void *peer_handler(void *p)
{
// ...

pthread_mutex_lock(&list_mutex);
if (numNodes == 0) {
head = newNode;
tail = newNode;
tail->next = NULL;
numNodes++;
}
else {
tail->next = newNode;
tail = newNode;
tail->next = NULL;
numNodes++;
}
pthread_mutex_unlock(&list_mutex);

// ...

pthread_mutex_lock(&list_mutex);
struct fileNode *ptr = head;
while (ptr != NULL) {
if ((strcmp(ptr->ip, temp_ip) == 0) && ptr->port == temp_port) {
cmd = htonl(200);
break;
}
ptr = ptr->next;
}
pthread_mutex_unlock(&list_mutex);

// ...
}

void sendList(int newsockfd)
{
// ...
pthread_mutex_lock(&list_mutex);
struct fileNode *ptr;
ptr = head;
while (ptr != NULL) {
// ...

ptr = ptr->next;

// ...
}
pthread_mutex_unlock(&list_mutex);
}

void removeFiles(uint32_t port, char *client_ip)
{
pthread_mutex_lock(&list_mutex);

// ...

pthread_mutex_unlock(&list_mutex);
}

void print()
{
// ...
pthread_mutex_lock(&list_mutex);
struct fileNode *ptr;
ptr = head;
while (ptr != NULL) {
// ...

ptr = ptr->next;

// ...
}
pthread_mutex_unlock(&list_mutex);
}

值得注意的是,减少锁争用是并发应用程序性能调优的重要组成部分。

Socket相关问题

send()recv() 函数不保证所有指定数量的字节 将用一个发送/接收函数调用。

应使用适当的循环来发送或接收所需(预期)的字节数。更多详情请引用文章:TCP/IP client-server application: exchange with string messages .

另外,要小心这样的结构:

n = recv(newsockfd, buffer, sizeof(buffer), 0); 
// ...
buffer[n] = '\0';

要接收的预期字节数(或在本例中为字符数)应为 sizeof(buffer) - 1。否则,数据丢失:最后一个字符被终止空字符覆盖。

关于multithreading - C 套接字编程中使用链表的线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33137604/

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