简体   繁体   English

pthread_create的参数在C ++中使用—每次线程函数获取值都相同,为什么?

[英]The argument of pthread_create was used in C++ — Every time the thread function get the value was the same, why?

I used pthread_create in C++, and the program runs, but in pthread function, the argument result was the same. 我在C ++中使用了pthread_create,程序运行了,但是在pthread函数中,参数结果是相同的。 Why? 为什么? I have used pthread_mutex_lock, but it is not effective. 我使用了pthread_mutex_lock,但是它无效。 I can't find out the reason. 我找不到原因。

The codes below: 以下代码:

Minimal: 最小:

const int MAX_THREADS = 5;
class FileCpThread
{
public:
FileCpThread(const string &src,const string & des){
srcFile = src.c_str();
desFile = des.c_str();
}
~FileCpThread(){}
startThreadCopy();

private:
static void *threadCp(void *param);
static int getFileSize(const std::string &filename);
string srcFile;
int num;
string desFile;
};

Complete: 完成:

bool FileCpThread::startThreadCopy()
{

pthread_t pid[MAX_THREADS];

pthread_mutex_init(&mutex, NULL);

for (int i = 0; i < MAX_THREADS; i++)
{
pthread_mutex_lock(&mutex);
this->num = i;
pthread_mutex_unlock(&mutex);
pthread_create(&pid[i], NULL, threadCp, (void *)this);
}

for (int j = 0; j < MAX_THREADS; j++)
{
pthread_join(pid[j], NULL);
}

return true;
}
int FileCpThread::getFileSize(const string &filename)
{
struct stat st;
memset(&st, 0, sizeof(st));
stat(filename.c_str(), &st);
return st.st_size;
}

void *FileCpThread::threadCp(void *param)
{
FileCpThread *ft = (FileCpThread *)param;
FILE *fin = fopen(ft->srcFile.c_str(), "r+");
FILE *fout = fopen(ft->desFile.c_str(), "w+");

int size = getFileSize(ft->srcFile.c_str());
pthread_mutex_lock(&ft->mutex);
int number =  ft->num;
pthread_mutex_unlock(&ft->mutex);
cout << "number:::" << number << endl;

fseek(fin, size * (number) / MAX_THREADS, SEEK_SET);
fseek(fout, size * (number) / MAX_THREADS, SEEK_SET);

char buff[1024] = {'\0'};
int len = 0;
int total = 0;
while ((len = fread(buff, 1, sizeof(buff), fin)) > 0)
{
fwrite(buff, 1, len, fout);
total += len;

if (total > size / MAX_THREADS)
{
  break;
}
}

fclose(fin);
fclose(fout);
}

Verifiable: 可验证的:

bool FileCpThread::startThreadCopy()

pthread_mutex_lock(&ft->mutex);
int number =  ft->num;
pthread_mutex_unlock(&ft->mutex);
cout << "number:::" << number << endl;

You get the same value in the thread function because you pass the same value to it each time. 您在线程函数中获得相同的值,因为每次都将相同的值传递给它。 Your code is: 您的代码是:

for (int i = 0; i < MAX_THREADS; i++)
{
    pthread_mutex_lock(&mutex);
    this->num = i;
    pthread_mutex_unlock(&mutex);
    pthread_create(&pid[i], NULL, threadCp, (void *)this);
}

The value of this does not change between iterations, so the same value is passed to threadCp each time it is used. this所以相同的值传递给不迭代之间变化, threadCp每次使用的时间。

If your problem is that all the threads see the same value for this->num , then the problem is still that you pass the same pointer to the function each time, but you also have the indeterminacy with which the threads are scheduled, and Sod's Law dictates that the threads won't be activated until the last one is created, so they all see the same value in this->num . 如果您的问题是所有线程都对this->num看到相同的值,那么问题仍然在于,您每次都将相同的指针传递给该函数,但是您还不确定线程​​的调度方式,而Sod的法律规定,直到创建最后一个线程,线程才会被激活,因此它们在this->num都看到相同的值。 You have to make sure that each thread gets independent information to work with — assuming each thread should be getting independent information. 您必须确保每个线程都可以使用独立的信息-假设每个线程都应该获取独立的信息。


For N threads, you need to create an array of N values — it appears that N int might be sufficient, and (a) set the elements appropriately and (b) pass one element of the array to each thread. 对于N个线程,您需要创建一个N个值的数组-看来N int可能就足够了,并且(a)适当地设置元素,并且(b)将数组的一个元素传递给每个线程。

As an element of the class: 作为类的元素:

int thread_number[MAX_THREADS];

As initialization: 作为初始化:

for (int i = 0; i < MAX_THREADS; i++)
    this->thread_number[i] = i;

In the call to pthread_create() : 在对pthread_create()的调用中:

pthread_create(&pid[i], NULL, threadCp, &this->thread_number[i]);

In the function threadCp() , instead of: 在函数threadCp() ,代替:

 FileCpThread *ft = (FileCpThread *)param; 

use: 采用:

int number = *(int *)param;

And you don't need the mutex for synchronization any more (at least, not to control access to the thread number). 而且您不再需要互斥锁进行同步(至少,不控制对线程号的访问)。

If the number of threads is variable, use a vector<int> . 如果线程数可变,请使用vector<int> If it would be more sensible to compute the split of the file before launching the threads, do that (it probably is sensible). 如果在启动线程之前计算文件的分割更为明智,则执行此操作(这可能是明智的)。

Do note that having 5 threads accessing separate portions of a single file is probably not going to improve overall performance. 请注意,有5个线程访问单个文件的不同部分可能不会提高整体性能。 As an exercise in coordination between processes, it is fine. 作为过程之间协调的练习,这很好。 As an exercise in improving overall performance, it is probably not a good idea. 作为提高整体性能的一项练习,这可能不是一个好主意。 (Reason: the file will be on a single file system, so the same controllers will be used in accessing the separate sections of disk, leading to head positioning contention. Performance might actually be worse than running single-threaded.) (原因:文件将在单个文件系统上,因此将使用相同的控制器访问磁盘的各个部分,从而导致磁头定位争用。实际上,性能可能比运行单线程还差。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM