从多个线程调用C文件中的函数

时间:2022-09-06 21:32:29

I am working with a code base with some .C files and .CPP files.

我正在使用带有一些.C文件和.CPP文件的代码库。

The multiple threads in the system calls some functions in C files as the one given below.

系统中的多个线程调用C文件中的一些函数,如下所示。

void CalculateCrc(PWORD pwCRC, PBYTE pbyBuffer, DWORD dwBufferLen)
{
    WORD wFCS = 0xffff;

    ASSERT(pbyBuffer);
    ASSERT(pwCRC);
    while(dwBufferLen--)
    {
        wFCS = (WORD)(wFCS >> 8) ^ tbl_FCS[(wFCS ^ *pbyBuffer++) & 0xff];
    }
    wFCS ^= 0xffff; // complement
    *pwCRC = wFCS;
}

For each calling thread will there be copies of arguments[pwCRC, pbyBuffer, dwBufferLen] and non-static data members of function [WORD wFCS], or will there be only a single set of data shared by all threads that will result in data corruption and make the calls from multiple threads unsafe?

对于每个调用线程,都会有参数[pwCRC,pbyBuffer,dwBufferLen]和函数[WORD wFCS]的非静态数据成员的副本,或者只有一组数据由所有线程共享,这将导致数据损坏并使来自多个线程的调用不安全?

I am not a native English speaker. Forgive me if the question is not asked in a clear manner.

我不是英语母语人士。如果问题没有以明确的方式提出,请原谅我。

Thanks for your time.

谢谢你的时间。

3 个解决方案

#1


3  

I believe each thread will have its own stack, which is a copy of the spawning process' stack (I hope I am technically correct on this one). They do share address space and heap though.

我相信每个线程都有自己的堆栈,这是产生进程堆栈的副本(我希望我在这个技术上是正确的)。他们确实共享地址空间和堆。

So anything that existed before spawn will be shared. Anything created after is thread-local. And since everything is passed by value, and data member is non-static, it will be created thread-local.

所以在spawn之前存在的任何东西都将被共享。之后创建的任何东西都是线程本地的。因为一切都是按值传递的,而数据成员是非静态的,所以它将被创建为线程局部的。

Your function per-se is safe. However, since you work with pointers, you need to take care that two threads do not work over the same memory area. The variables are safe, the memory is not.

您的功能本身是安全的。但是,由于您使用指针,因此需要注意两个线程不能在同一个内存区域上工作。变量是安全的,而内存则不是。

#2


1  

The function will have its own copy of pwCRC and dwBufferLen BUT NOT pbyBuffer because you are passing it as a pointer.

该函数将拥有自己的pwCRC和dwBufferLen副本但不是pbyBuffer,因为您将它作为指针传递。

I give two solutions:

我给出两个解决方案:

A. ensure that all threads only have read (or no) access to pbyBuffer while this function is called; or (if the data is rather small

A.确保所有线程在调用此函数时只读取(或不读取)pbyBuffer;或(如果数据相当小)

You could do this by making a copy.

你可以通过制作副本来做到这一点。

B. Pass the buffer by value. you can do this by using a structure

B.按值传递缓冲区。你可以通过使用一个结构来做到这一点

struct buffer { char buffer [LEN] ; }

struct buffer {char buffer [LEN]; }

This only works if the buffer is small. If I remember correctly, the C++ standard limits the size of the call stack as a concession to the VAX architecture. Your compiler might exceed the limits of the standard. Even so, it is not a good idea to kill the stack with large arguments.

这仅在缓冲区很小时才有效。如果我没记错的话,C ++标准将调用堆栈的大小限制为对VAX架构的让步。您的编译器可能超出标准的限制。即便如此,使用大型参数杀死堆栈也不是一个好主意。

#3


1  

will there be copies of arguments[pwCRC, pbyBuffer, dwBufferLen]

会不会有参数副本[pwCRC,pbyBuffer,dwBufferLen]

In C, the arguments are passed by value, so for each call from different threads these will have different copied. However, if the passed variables are global/shared by the threads then all such threads will pass the same variables.

在C中,参数是通过值传递的,因此对于来自不同线程的每个调用,它们将被复制不同。但是,如果传递的变量是线程全局/共享的,那么所有这些线程都将传递相同的变量。

In your case PWORD pwCRC, PBYTE pbyBuffer are pointers. If these are shared between the threads then also, your function is not thread-safe. As multiple threads may try to change the value pointed by these pointers.

在你的情况下,PWORD pwCRC,PBYTE pbyBuffer是指针。如果这些在线程之间共享,那么你的函数也不是线程安全的。由于多个线程可能会尝试更改这些指针指向的值。

non-static data members of function [WORD wFCS]

函数的非静态数据成员[WORD wFCS]

Yes, there will be copy for each function call.

是的,每个函数调用都会有副本。

#1


3  

I believe each thread will have its own stack, which is a copy of the spawning process' stack (I hope I am technically correct on this one). They do share address space and heap though.

我相信每个线程都有自己的堆栈,这是产生进程堆栈的副本(我希望我在这个技术上是正确的)。他们确实共享地址空间和堆。

So anything that existed before spawn will be shared. Anything created after is thread-local. And since everything is passed by value, and data member is non-static, it will be created thread-local.

所以在spawn之前存在的任何东西都将被共享。之后创建的任何东西都是线程本地的。因为一切都是按值传递的,而数据成员是非静态的,所以它将被创建为线程局部的。

Your function per-se is safe. However, since you work with pointers, you need to take care that two threads do not work over the same memory area. The variables are safe, the memory is not.

您的功能本身是安全的。但是,由于您使用指针,因此需要注意两个线程不能在同一个内存区域上工作。变量是安全的,而内存则不是。

#2


1  

The function will have its own copy of pwCRC and dwBufferLen BUT NOT pbyBuffer because you are passing it as a pointer.

该函数将拥有自己的pwCRC和dwBufferLen副本但不是pbyBuffer,因为您将它作为指针传递。

I give two solutions:

我给出两个解决方案:

A. ensure that all threads only have read (or no) access to pbyBuffer while this function is called; or (if the data is rather small

A.确保所有线程在调用此函数时只读取(或不读取)pbyBuffer;或(如果数据相当小)

You could do this by making a copy.

你可以通过制作副本来做到这一点。

B. Pass the buffer by value. you can do this by using a structure

B.按值传递缓冲区。你可以通过使用一个结构来做到这一点

struct buffer { char buffer [LEN] ; }

struct buffer {char buffer [LEN]; }

This only works if the buffer is small. If I remember correctly, the C++ standard limits the size of the call stack as a concession to the VAX architecture. Your compiler might exceed the limits of the standard. Even so, it is not a good idea to kill the stack with large arguments.

这仅在缓冲区很小时才有效。如果我没记错的话,C ++标准将调用堆栈的大小限制为对VAX架构的让步。您的编译器可能超出标准的限制。即便如此,使用大型参数杀死堆栈也不是一个好主意。

#3


1  

will there be copies of arguments[pwCRC, pbyBuffer, dwBufferLen]

会不会有参数副本[pwCRC,pbyBuffer,dwBufferLen]

In C, the arguments are passed by value, so for each call from different threads these will have different copied. However, if the passed variables are global/shared by the threads then all such threads will pass the same variables.

在C中,参数是通过值传递的,因此对于来自不同线程的每个调用,它们将被复制不同。但是,如果传递的变量是线程全局/共享的,那么所有这些线程都将传递相同的变量。

In your case PWORD pwCRC, PBYTE pbyBuffer are pointers. If these are shared between the threads then also, your function is not thread-safe. As multiple threads may try to change the value pointed by these pointers.

在你的情况下,PWORD pwCRC,PBYTE pbyBuffer是指针。如果这些在线程之间共享,那么你的函数也不是线程安全的。由于多个线程可能会尝试更改这些指针指向的值。

non-static data members of function [WORD wFCS]

函数的非静态数据成员[WORD wFCS]

Yes, there will be copy for each function call.

是的,每个函数调用都会有副本。