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