C 停止其他线程和多步碰撞的线程标志

C 停止其他线程和多步碰撞的线程标志,c,multithreading,pthreads,C,Multithreading,Pthreads,我有以下代码(我删除了一些不相关的部分) 通过这段代码,我可以使“connect\u ip”中的线程不再启动,但当前线程仍在运行,我也想停止它们(仅限“connect\u ip”中的线程) 结构域列表{ 字符域[20]; 结构域列表*下一步; }; 类型定义结构参数{ 无符号长ip; 字符域[30]; int X; int stop; }arg_结构; 结构域\列表*第一个\域=空; int main() { //缺少从文件代码加载到结构中 对于(i=0;iip=ip; args->X=ex;

我有以下代码(我删除了一些不相关的部分)

通过这段代码,我可以使“connect\u ip”中的线程不再启动,但当前线程仍在运行,我也想停止它们(仅限“connect\u ip”中的线程)

结构域列表{ 字符域[20]; 结构域列表*下一步; }; 类型定义结构参数{ 无符号长ip; 字符域[30]; int X; int stop; }arg_结构; 结构域\列表*第一个\域=空; int main() { //缺少从文件代码加载到结构中 对于(i=0;idomain,curr\u domain->domain,sizeof(args->domain)-1); args->ip=ip; args->X=ex; 参数->停止=停止; pthread_mutex_unlock(&thrd_列表); if(pthread_create(&thread_id[t],NULL,checkip,args)!=0) { t--; fprintf(stderr,红色“\n创建线程时出错\n”无); } 其他的 { pthread_mutex_lock(&thrd_列表); 如果(当前域->下一步!=NULL) 当前域=当前域->下一步; 其他的 退出=1; pthread_mutex_unlock(&thrd_列表); } } 对于(t=0;t停止; 免费(args); } } 如果(退出==1 | |停止==1) 打破 }//结束时 } void*checkip(void*arguments) { arg_struct*args=参数; 如果(参数->X==1) 返回args; int sock=0,ex=0,ret=0; 结构输入地址输入; t_in.s_addr=ntohl(args->ip); sock=检查端口(args->ip,80); 如果(sock==-1) { args->X=1; 返回args; } //缺少一些代码 如果(ret==1) args->stop=1; 返回args; } 第一个问题是如何使“connect_ip”中的所有线程在ret=1处于void“checkip”时停止,而不影响“start”void中的其他线程


第二个问题是在这种情况下如何正确使用pthread\u mutex\u lock,以便“start”和“connect\u ip”中的线程将数据弄乱?

两个快速观察。首先,为什么要在for循环中这样做:“我--;”。因此,线程标识符可能位于线程id数组中的不同索引中。其次,在connect_ip()函数中使用与“t--;”相同的内容。这可能会导致pthread_join()在执行pthread_join()时引用错误的线程ID

请在评论中查找其他文本

添加一个快速示例,允许单个connect_Ip线程在其子线程之间维护一个公共信号变量。该示例人为地为索引为1的connect_ip线程设置全局变量。这样,一旦设置了信号,connect_ip线程的所有(三)子线程都将停止。另一方面,另一个父线程(使用索引0连接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");
        }
    }

}

两个快速观察。首先,为什么要在for循环中这样做:“我--;”。因此,线程标识符可能位于线程id数组中的不同索引中。其次,在connect_ip()函数中使用与“t--;”相同的内容。这可能会导致pthread_join()在执行pthread_join()时引用错误的线程ID

请在评论中查找其他文本

添加一个快速示例,允许单个connect_Ip线程在其子线程之间维护一个公共信号变量。该示例人为地为索引为1的connect_ip线程设置全局变量。这样,一旦设置了信号,connect_ip线程的所有(三)子线程都将停止。另一方面,另一个父线程(使用索引0连接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");
        }
    }

}

这与清洁资源无关。在void“checkip”中,我有一个来自另一个结构的长循环,当找到记录时,它退出循环并返回ret=1,因此来自connect_ip(相同的ip,不同的套接字)的所有其他线程必须停止,即使它们在mso上运行,也必须有一些标志触发其他线程停止。我已经这么做了,但是该标志触发了所有线程,不仅停止了来自connect\u ip的线程,因此它是无用的。如果从connect\u ip创建的线程返回,而来自conenct\u ip的调用线程没有任何其他事情要做,那么只有(connect\u ip)线程应该返回,而不是其他线程。你能用旗子显示代码吗。另外,请删除“i--”和“t--”,因为它们可能会影响pthread_join()调用。我认为它们不会影响pthread_join()调用
$ ./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