views:

84

answers:

3

is a c++ member array of struct thread safe using only one index per thread ?

using the following class:

typedef struct {
    bool bFlag;
    unsigned int uiNum;
} TC_MYSTRUCT;

class MyClass {
public:
    MyClass();
    ~MyClass();
    int GetFreeIndex();
    void SetIndexDataNum(int idx, int num);
    int GetIndexDataNum(int idx);
private:
    TC_MYSTRUCT m_arr[10];
};
  • this class is defined as a global var.
  • GetFreeIndex() is synchronized with critical section ...
  • there are some threads getting a free index from the member array with GetFreeIndex()
  • SetIndexDataNum modifies it's own unique entry within m_arr.
  • within a thread SetIndexDataNum/GetIndexDataNum are called only with the thread specific index
  • SetIndexDataNum/GetIndexDataNum can be called at the same time, but with different index
  • SetIndexDataNum/GetIndexDataNum are never called at the same time within a thread

is it thread safe to use methods SetIndexDataNum/GetIndexDataNum without critical section inside ? (since the are addressing only a specific array index)

A: 

It is not clear if SetIndexDataNum/GetIndexDataNum modify any member of the class? I guess they do.

If they do, then it is not safe without Critical Section.

Chubsdad
SetIndexDataNum/GetIndexDataNum are only called within the thread with the thread specific index and they are only modifying TC_MYSTRUCT members.
jwei
So, SetIndexDataNum modifies it's own unique entry within m_arr? If that is the case, then there needs to be a critical section to synchronize SetIndexDataNum and GetIndexDataNum
Chubsdad
So if each thread has it's own TC_MYSTRUCT based on thread index then you don't need any synchronization at all.
adf88
yes, SetIndexDataNum modifies it's own unique entry within m_arr. and in addition: GetIndexDataNum is also called only within the same thread: so SetIndexDataNum/GetIndexDataNum are never called at the same time for a specific index
jwei
But there is a global variable of your class which is shared across your threads. It requires synchronizing SetIndexDataNum/GetIndexDataNum as they both write/read the same memory location i.e. m_arr[someindex];
Chubsdad
@chubsdad: well i am wronng here. Set and Get are not called at the same time. So no need to synchronize.
Chubsdad
SetIndexDataNum/GetIndexDataNum can be called at the same time, but with different index
jwei
Yes, since a thread can be calling either Set or Get of the global object, synchronizing them is not required.
Chubsdad
A: 

If they are just referring to "locked" cell then yes. But it should be designed a litter different. Your thread safe class should have two methods - one that acquires a resource that a thread would use freely and second - to release a resource. All operations on a resource should be accessible from it, not from the MyClass. You should be forced to "lock" a resource before you can use it:

struct TC_MYSTRUCT {
    bool bFlag;
    unsigned int uiNum;
    void Action();
};

class MyClass {
public:
    MyClass();
    ~MyClass();
    TC_MYSTRUCT *GetFreeResource();
    void ReleaseResource(TC_MYSTRUCT *resource);
private:
    TC_MYSTRUCT m_arr[10];
};

/* thread */
TC_MYSTRUCT *resource = my_class.GetFreeResource();
resource->Action();
my_class.ReleaseResource(resource);
adf88
A: 

If GetFreeIndex is correctly synchronized, and never returns the same index twice, and a given index value is never shared between threads then calls to SetIndexDataNum and GetIndexDataNum do not require synchronization if they are simple array index operations, as separate threads are accessing separate objects.

If the index values are shared across threads then you will definitely need synchronization. If the get/set functions are more complex than a simple array index then they may need synchronization anyway.

Anthony Williams