我正在使用对等点和跟踪器实现 P2P 文件传输。跟踪器跟踪所有对等点及其文件,并且对等点在想要下载文件时连接到另一个对等点并且还接受来自其他对等点的下载其文件之一的请求。为此,我的对等点既充当其他对等点的客户端和服务器,又充当跟踪器的客户端。为此,我使用线程并将服务器进程放在一个线程中,将客户端进程放在另一个线程中,将连接到主线程中的跟踪器的进程放在线程中。当对等方选择退出时,我也想关闭其服务器进程,即:单独服务器线程中的进程。我尝试制作一个包含文件描述符的全局变量,以便在客户端退出时关闭它,但这在我退出后给我一个错误。
这是我的同行代码:
最佳答案
如果你想知道如何从主线程中停止其他线程,这里是一种方法。我会创建一个结构,让我们称它为 thread_state_t
,它有一个标志告诉你的线程停止,例如称它为 active
。在线程中,您检查循环的值并根据状态执行任何您需要的操作。
在简单的情况下,它看起来像这样
#include <stdio.h>
#include <pthread.h>
typedef struct {
int active;
} thread_state_t;
void* t1(void* arg) {
thread_state_t* state = (thread_state_t*) arg;
while(state->active > 0) {
// do work
}
return NULL;
}
int main() {
pthread_t tid;
thread_state_t state1;
state1.active = 1;
pthread_create(&tid, NULL, t1, (void*)&state1);
// ...
state1.active = 0;
// ...
pthread_join(tid, NULL);
return 0;
}
但是这个例子只是为了向您展示主要思想。在实际实现中,您需要使 active
变量或整个 thread_state_t
对象线程安全(例如使用 mutex
)。
为了使其线程安全,您可以使用向状态对象添加互斥锁
typedef struct {
pthread_mutex_t mutex;
int active;
} thread_state_t;
并添加一些像这样的函数
void init_state(thread_state_t* state) {
state->active = 1;
pthread_mutex_init(&state->mutex, NULL);
}
void remove_state(thread_state_t* state) {
state->active = 0;
pthread_mutex_destroy(&state->mutex);
}
int get_active(thread_state_t* state) {
int active = 0;
pthread_mutex_lock(&state->mutex);
active = state->active;
pthread_mutex_unlock(&state->mutex);
return active;
}
void set_active(thread_state_t* state, int active) {
pthread_mutex_lock(&state->mutex);
state->active = active;
pthread_mutex_unlock(&state->mutex);
}
然后将循环条件从 state->active > 0
更改为 get_active(state) > 0
,主线程中的代码将如下所示(sleep
此处调用仅供示例)
int main() {
pthread_t tid;
thread_state_t state;
init_state(&state);
pthread_create(&tid, NULL, t1, (void*)&state);
sleep(1);
set_active(&state, 0);
pthread_join(tid, NULL);
remove_state(&state);
return 0;
}
还有另一种使用方式 pthread_cancel
.然而,这不是最好的解决方案。
关于从主线程关闭套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33139877/