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.
是的,每个函数调用都会有副本。