我有以下代码(我删除了一些不相关的部分)
使用此代码,我可以使“connect_ip”中的线程不再启动,但当前的线程仍在运行,我也想停止它们(只有“connect_ip”中的那些)
struct domain_list {
char domain[20];
struct domain_list * next;
};
typedef struct arg_struct {
unsigned long ip;
char domain[30];
int X;
int stop;
}arg_struct;
struct domain_list * first_domain = NULL;
int main()
{
//loading into structure from file code is missing
for(i = 0 ; i < number_thread; i++)
{
if(pthread_create(&thread_id[i],NULL,&start,NULL) != 0)
{
i--;
fprintf(stderr,RED "\nError in creating thread\n" NONE);
}
}
for(i = 0 ; i < number_thread; i++)
if(pthread_join(thread_id[i],NULL) != 0)
{
fprintf(stderr,RED "\nError in joining thread\n" NONE);
}
}
void * start(void * data)
{
unsigned long ip = 0xffffffff;
char ip[20];
while (!feof(INFILE))
{
if (fgets(ip,sizeof(ip),INFILE) != NULL)
{
if (strlen(ip) < 8)
break;
if (ip[strlen (ip) - 1] == '\n')
ip[strlen (ip) - 1] = '\0';
ip = ntohl((unsigned long)inet_addr(ip));
}
connect_ip(ip);
}
return NULL;
}
void connect_ip(unsigned long ip)
{
struct domain_list * curr_domain = first_domain;
int exit=0,stop=0;
while(curr_domain)
{
for(t = 0 ; t < ip_thread; t++)
{
pthread_mutex_lock(&thrd_list);
arg_struct *args = calloc(1, sizeof(*args));
strncpy(args->domain,curr_domain->domain,sizeof(args->domain) - 1);
args->ip = ip;
args->X = ex;
args->stop = stop;
pthread_mutex_unlock(&thrd_list);
if(pthread_create(&thread_id[t],NULL,checkip,args) != 0)
{
t--;
fprintf(stderr,RED "\nError in creating thread\n" NONE);
}
else
{
pthread_mutex_lock(&thrd_list);
if(curr_domain->next != NULL)
curr_domain = curr_domain->next;
else
exit = 1;
pthread_mutex_unlock(&thrd_list);
}
}
for(t = 0 ; t < ip_thread; t++)
{
void *join_result;
if(pthread_join(thread_id[t],&join_result) != 0)
{
fprintf(stderr,RED "\nError in joining thread\n" NONE);
}
else
{
arg_struct *args = join_result;
stop = args->stop;
free(args);
}
}
if (exit == 1 || stop == 1)
break;
}//end while
}
void *checkip(void *arguments)
{
arg_struct *args = arguments;
if (args->X == 1)
return args;
int sock = 0,ex = 0,ret = 0;
struct in_addr t_in;
t_in.s_addr = ntohl(args->ip);
sock = check_port(args->ip,80);
if(sock == -1)
{
args->X = 1;
return args;
}
//some code missing
if(ret == 1)
args->stop = 1;
return args;
}
第一个问题是如何使“connect_ip”中的所有线程在void“checkip”中的ret = 1时停止,而不影响“start”中的其他线程?
第二个问题是在这种情况下如何正确使用pthread_mutex_lock所以线程从“开始”和那些来自“connect_ip”来搞乱数据?
答案 0 :(得分:1)
两个快速观察。首先,你为什么要在for循环中这样做:“我 - ;”。因此,线程标识符可能位于thread_id数组中的不同索引中。第二,同样的“t--”在connect_ip()函数中。这可能导致pthread_join()在执行pthread_join()时引用不正确的线程ID。
请在评论中查找其他文字。
添加一个快速示例,允许各个connect_Ip线程在其子线程中维护一个公共信号变量。该示例人工设置connect_ip线程的全局变量和索引1.这样,一旦设置了信号,connect_ip线程的所有(三个)子线程都会停止。另一方面,另一个父线程(带索引0的connect_ip)继续运行:
#include <stdio.h>
#include <pthread.h>
#define TEMP_MAX_THREADS 2
#define TEMP_MAX_CHILD_THREADS 3
int stop[TEMP_MAX_THREADS];
typedef struct two_ints_ {
int parent_index;
int child_index;
int *common_stop_all_children;
} two_ints;
void *check_ip (void *arg) {
int i = 0, temp;
two_ints *x = (two_ints *)arg;
printf("\t%s Starting to run (index: %d parent: %d) \n",
__FUNCTION__, x->child_index, x->parent_index);
srand(time(NULL));
while (i++ < 10){
printf("\t%s Me wokeup (index: %d parent: %d) \n",
__FUNCTION__, x->child_index, x->parent_index);
sleep(1);
if (x->parent_index == 1) {
if (*(x->common_stop_all_children) == 1) {
printf("\t%s Other thread has set the stop signal (index: %d parent: %d). Return\n",
__FUNCTION__, x->child_index, x->parent_index);
return;
}
temp = rand() % 4;
if (temp == 2) {
printf("\t%s Time to return. Let us set the global stop to 1 (index: %d parent: %d) \n",
__FUNCTION__, x->child_index, x->parent_index);
*(x->common_stop_all_children) = 1;
return;
}
}
}
return NULL;
}
void *connect_ip (void *arg) {
int common_stop_all_children = 0;
pthread_t child_thread_id[TEMP_MAX_CHILD_THREADS];
two_ints arg_two_ints[TEMP_MAX_CHILD_THREADS];
int i;
printf("I am here with index: %d \n", *(int *)arg);
for(i = 0 ; i < TEMP_MAX_CHILD_THREADS; i++) {
arg_two_ints[i].parent_index = *(int *)arg;
arg_two_ints[i].child_index = i;
arg_two_ints[i].common_stop_all_children = &common_stop_all_children;
if(pthread_create(&child_thread_id[i], NULL, check_ip, (void*) &arg_two_ints[i]) != 0) {
fprintf(stderr, "\nError in creating thread\n" );
}
}
for(i = 0 ; i < TEMP_MAX_CHILD_THREADS; i++) {
if(pthread_join(child_thread_id[i], NULL) != 0) {
fprintf(stderr, "\npthread_join failed\n" );
}
}
return NULL;
}
int main() {
pthread_t thread_id[TEMP_MAX_THREADS];
int index[TEMP_MAX_THREADS];
int i;
for(i = 0 ; i < TEMP_MAX_THREADS; i++) {
index[i] = i;
if(pthread_create(&thread_id[i], NULL, connect_ip, (void *)&index[i]) != 0) {
fprintf(stderr, "\nError in creating thread\n" );
}
}
for(i = 0 ; i < TEMP_MAX_THREADS; i++) {
if(pthread_join(thread_id[i], NULL) != 0) {
fprintf(stderr, "\npthread_join failed\n");
}
}
}
以下是输出示例。
$ ./a.out
I am here with index: 1
I am here with index: 0
check_ip Starting to run (index: 0 parent: 1)
check_ip Starting to run (index: 1 parent: 1)
check_ip Me wokeup (index: 0 parent: 1)
check_ip Starting to run (index: 0 parent: 0)
check_ip Starting to run (index: 2 parent: 1)
check_ip Me wokeup (index: 1 parent: 1)
check_ip Starting to run (index: 1 parent: 0)
check_ip Starting to run (index: 2 parent: 0)
check_ip Me wokeup (index: 0 parent: 0)
check_ip Me wokeup (index: 2 parent: 1)
check_ip Me wokeup (index: 1 parent: 0)
check_ip Me wokeup (index: 2 parent: 0)
check_ip Me wokeup (index: 2 parent: 1)
check_ip Me wokeup (index: 0 parent: 0)
check_ip Time to return. Let us set the global stop to 1 (index: 1 parent: 1)
check_ip Me wokeup (index: 1 parent: 0)
check_ip Me wokeup (index: 2 parent: 0)
check_ip Me wokeup (index: 0 parent: 1)
check_ip Me wokeup (index: 2 parent: 0)
check_ip Other thread has set the stop signal (index: 2 parent: 1). Return
check_ip Me wokeup (index: 0 parent: 0)
check_ip Me wokeup (index: 1 parent: 0)
check_ip Other thread has set the stop signal (index: 0 parent: 1). Return
check_ip Me wokeup (index: 2 parent: 0)
check_ip Me wokeup (index: 0 parent: 0)
check_ip Me wokeup (index: 1 parent: 0)
check_ip Me wokeup (index: 1 parent: 0)
check_ip Me wokeup (index: 0 parent: 0)
check_ip Me wokeup (index: 2 parent: 0)
check_ip Me wokeup (index: 2 parent: 0)
check_ip Me wokeup (index: 1 parent: 0)
check_ip Me wokeup (index: 0 parent: 0)
check_ip Me wokeup (index: 2 parent: 0)
check_ip Me wokeup (index: 0 parent: 0)
check_ip Me wokeup (index: 1 parent: 0)
check_ip Me wokeup (index: 2 parent: 0)
check_ip Me wokeup (index: 1 parent: 0)
check_ip Me wokeup (index: 0 parent: 0)
^C