c语言中的多线程搜索

c语言中的多线程搜索,c,arrays,multithreading,C,Arrays,Multithreading,我假设有两个线程搜索数组中的最小元素:第一个线程搜索前一半,第二个线程搜索另一半。然而,当我运行代码时,它似乎随机选择了一个线程。我不确定我做错了什么,但这可能与“中间”部分有关。我试着把一个数组一分为二,找到中点,然后从那里写出条件,但我可能在某个地方出错了。我还尝试将数组[I]放入条件中,但在这种情况下,只执行thread2 编辑:我在这里真的尽了最大努力,但我一事无成。我以一种对我有意义的方式编辑了代码,我可能键入了“min”错误,但现在它甚至没有执行,只是给了我一个错误,尽管它编译得很好

我假设有两个线程搜索数组中的最小元素:第一个线程搜索前一半,第二个线程搜索另一半。然而,当我运行代码时,它似乎随机选择了一个线程。我不确定我做错了什么,但这可能与“中间”部分有关。我试着把一个数组一分为二,找到中点,然后从那里写出条件,但我可能在某个地方出错了。我还尝试将数组[I]放入条件中,但在这种情况下,只执行thread2


编辑:我在这里真的尽了最大努力,但我一事无成。我以一种对我有意义的方式编辑了代码,我可能键入了“min”错误,但现在它甚至没有执行,只是给了我一个错误,尽管它编译得很好。我只是一个初学者,虽然我确实理解你们所谈论的一切,但我很难实现这些想法,所以真的,任何关于修复这些问题的帮助都是非常感谢的

EDIT2:好吧,前面的代码毫无意义,我很抱歉,但我在写的时候已经筋疲力尽了。不管怎样,我想出了另一个部分有效的方法!我将数组分成两半,但是使用指针时只能访问第一个元素。但是,如果整个阵列都被访问,它会工作吗?如果是,我该如何修复它

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>

#define size 20

void *smallest(void *arg);
pthread_t th, th2;
int array[size], i, min;

int main(int argc, char *argv[]) {

srand ( time(NULL) );
      for(i = 0; i < size; i++)
      {
              array[i] = (rand() % 100)+1;
              printf("%d ", array[i]);
   }

   int *array1 = malloc(10 * sizeof(int));
   int *array2 = malloc(10 * sizeof(int));
   memcpy(array1, array, 10 * sizeof(int));
   memcpy(array2, array + 10, 10 * sizeof(int));

    printf("\nFirst half gives %d \n", *array1);
    printf("Second half gives %d \n", *array2);


    pthread_create(&th, NULL, smallest, (void*) array1);
    pthread_create(&th2, NULL, smallest, (void*) array2);

    pthread_join(th, NULL);
    pthread_join(th2, NULL);

    //printf("\nFirst half gives %d\n", array1);
    //printf("Second half gives %d\n", array2);


if (*array1 < *array2) {
    printf("\nThread1 finds the number\n");
    printf("The smallest element is %i\n", *array1);
}
else {
    printf("\nThread2 finds the number\n");
    printf("The smallest element is %i\n", *array2);
}

return 0;
}

void *smallest(void* arg){

int *array = (int*)arg;

min = array[0];
for (i = 0; i < size; i++) {
  if (array[i] < min) {
     min = array[i];
  }
}
pthread_exit(NULL);
}
#包括
#包括
#包括
#包括
#定义尺寸20
void*最小值(void*arg);
pthread_t th,th2;
int数组[size],i,min;
int main(int argc,char*argv[]){
srand(时间(空));
对于(i=0;i
您设置的代码不会运行多个线程。请注意,如果运行if语句的第一个分支,则会触发一个线程来搜索数组的一半,等待它完成,然后继续,如果执行else分支,则在数组的后半部分也会发生同样的情况。从根本上说,您可能希望重新考虑您的策略,让代码始终启动两个线程,并且只有在两个线程都开始运行后才连接它们

if语句中的条件似乎也是错误的。您询问的是数组的中间元素是否大于其索引。我想这不是你想做的

最后,每个线程中的代码总是查看整个数组,而不仅仅是其中的一半。我建议重写线程例程,使其参数表示要取最小值的范围的开始和结束索引。然后更新main中的代码,以便在触发线程时指定要搜索的范围

我会这样安排:

pthread_create(&th, NULL, &smallest, NULL);
pthread_create(&th2, NULL, &smallest, NULL);
pthread_join(th2, NULL);
pthread_join(th, NULL);
  • 触发一个线程以查找数组前半部分的最小值
  • 触发一个线程以查找数组后半部分的最小值
  • 连接两个线程
  • 使用每个线程的结果找出最小值

  • 最后一点要注意的是,由于您将有两个不同的线程同时运行,因此当两个线程都尝试读取或写入最小值时,您需要注意数据争用。考虑每个线程使用它的退出代码来指示最小值在哪里,然后在主线程中返回真正的最小值。这消除了竞争条件。或者,使用一个全局最小值,但使用互斥锁对其进行保护。

    这是您所要求的单线程版本

    #include <stdio.h>
    #include <stdlib.h>
    
    /*
    I can not run pthread on my system.
    So this is some code that should kind of work the same way
    */
    typedef int pthread_t;
    typedef int pthread_attr_t;
    typedef void*(*threadfunc)(void*);
    
    int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg)
    {
        start_routine(arg);
        return 0;
    }
    
    int pthread_join(pthread_t thread, void **value_ptr)
    {
        return 0;
    }
    
    struct context
    {
        int* begin;
        int* end;
        int* result;
    };
    
    //the function has to be castable to the threadfunction type
    //that way you do not have to worry about casting the argument.
    //be careful though - if something does not match these errors may be hard to track
    void * smallest(context * c) //signature needet for start routine
    {
        c->result = c->begin;
        for (int* current = c->begin; current < c->end; ++current)
        {
            if (*current < *c->result)
            {
                c->result = current;
            }
        }
        return 0; // not needet with the way the argument is set up.
    }
    
    int main(int argc, char *argv[])
    {
        pthread_t t1, t2;
    #define size 20
        int array[size];
        srand(0);
        for (int i = 0; i < size; ++i)
        {
            array[i] = (rand() % 100) + 1;
            printf("%d ", array[i]);
        }
    
        //prepare data
        //one surefire way of messing up in multithreading is sharing data between threads.
        //even a simple approach like storing in a variable who is accessing will not solve the issues
        //to properly lock data you would have to dive into the memory model.
        //either lock with mutexes or memory barriers or just don' t share data between threads.
        context c1;
        context c2;
        c1.begin = array;
        c1.end = array + (size / 2);
        c2.begin = c1.end + 1;
        c2.end = array + size;
    
        //start threads - here your threads would go
        //note the casting - you may wnt to wrap this in its own function
        //there is error potential here, especially due to maintainance etc...
        pthread_create(&t1, 0, (void*(*)(void*))smallest, &c1); //without typedef
        pthread_create(&t2, 0, (threadfunc)smallest, &c2); //without typedef
    
        pthread_join(t1, 0);//instead of zero you could have a return value here
        pthread_join(t1, 0);//as far as i read 0 throws the return value away
        //return value could be useful for error handling
    
        //evaluate
        if (*c1.result < *c2.result)
        {
            printf("\nThread1 finds the number\n");
            printf("The smallest element is %i\n", *c1.result);
        }
        else
        {
            printf("\nThread2 finds the number\n");
            printf("The smallest element is %i\n", *c2.result);
        }
    
        return 0;
    }
    
    #包括
    #包括
    /*
    我无法在系统上运行pthread。
    所以这是一些应该以同样的方式工作的代码
    */
    typedef int pthread_t;
    typedef int pthread_attr;
    typedef void*(*threadfunc)(void*);
    int pthread_create(pthread_t*thread,const pthread_attr_t*attr,void*(*start_例程)(void*),void*arg)
    {
    启动程序(arg);
    返回0;
    }
    int pthread\u join(pthread\u t thread,void**value\u ptr)
    {
    返回0;
    }
    结构上下文
    {
    int*开始;
    int*结束;
    int*结果;
    };
    //该函数必须可强制转换为threadfunction类型
    //这样你就不必担心争论的结果了。
    //但是要小心——如果有不匹配的地方,这些错误可能很难跟踪
    void*最小(context*c)//开始例程的签名需求
    {
    c->result=c->begin;
    对于(int*current=c->begin;currentend;++current)
    {
    如果(*当前<*c->结果)
    {
    c->结果=当前;
    }
    }
    返回0;//不需要设置参数的方式。
    }
    int main(int argc,char*argv[])
    {
    pthread_t t1,t2;
    #定义尺寸20
    int数组[大小];
    srand(0);
    对于(int i=0;i if (array[mid] > mid) {
        pthread_create(&th, NULL, &smallest, NULL);
        pthread_join(th, NULL);
        printf("\nThread1 finds the number\n");
      }
      else if (array[mid] < mid) {
        pthread_create(&th2, NULL, &smallest, NULL);
        pthread_join(th2, NULL);
        printf("\nThread2 finds the number\n");
      }
    
    pthread_create(&th, NULL, &smallest, NULL);
    pthread_create(&th2, NULL, &smallest, NULL);
    pthread_join(th2, NULL);
    pthread_join(th, NULL);