指向包含互斥量的结构的 const 指针

const pointer to struct containing a mutex

我有这样的东西:

typedef struct
{
    pthread_mutex_t mtx;
    /* Other stuff */
} some_struct_t;

void some_func (some_struct_t *s)
{
    pthread_mutex_lock (&s->mtx);
    /* Some stuff */
    pthread_mutex_unlock (&s->mtx);
}

some_func不修改s,我想把签名改成

void some_func (const some_struct_t *s);

但是调用 pthreads 函数不允许我在没有警告的情况下这样做。

有什么常用的习语可以用来表达 some_struct_t 在函数中逻辑上 常量吗?

有什么方法可以在另一个具有 const some_struct_t *s 的函数中使用 some_func 而无需进行转换?

some_func修改了mtx成员,所以不能是const。

但是你可以让mtx成为一个指针。然后您仍然更改互斥锁,但它将不再被 const 覆盖。

typedef struct
{
    pthread_mutex_t *mtx;
    /* Other stuff */
} some_struct_t;

void some_func(const some_struct_t *s)
{
    pthread_mutex_lock(s->mtx);
    /* Some stuff */
    pthread_mutex_unlock(s->mtx);
}

int main()
{
    pthread_mutex_t mtx = MUTEX_INITIALIZER;
    some_struct s = {
        .mtx = &mtx;
    };
    some_func(&s);
}

现在 some_func 不再修改 s,但初始化 some_struct 变量(并清理它)变得更加复杂。

扩展 ,您可以在 some_struct_t 中有一个指向同一个 mutex 的冗余指针,并使用它代替真正的 mutex 的地址:

typedef struct
{
    pthread_mutex_t pmtx;
    pthread_mutex_t *mtx;
    /* Other stuff */
} some_struct_t;

void some_func (const some_struct_t *s)
{
    pthread_mutex_lock (s->mtx);
    /* Some stuff */
    pthread_mutex_unlock (s->mtx);
}

int main ()
{
    some_struct_t  s;

    pthread_mutex_init (&s.pmtx, NULL);
    s.mtx = &s.pmtx;
    some_func (&s);
    pthread_mutex_destroy (&s.pmtx);
}

或者,您可以通过在另一个参数中传递指向 mutex 的指针来欺骗编译器,并使用宏将实现细节隐藏到 programmer/user:

#define some_func(a)      some_func_hidden (a, &(a)->mtx)

typedef struct
{
    pthread_mutex_t mtx;
    /* Other stuff */
} some_struct_t;

void some_func_hidden (const some_struct_t *s, pthread_mutex_t *mtx)
{
    pthread_mutex_lock (mtx);
    /* Some stuff */
    pthread_mutex_unlock (mtx);
}

int main ()
{
    some_struct_t  s;

    pthread_mutex_init (&s.mtx, NULL);
    some_func (&s);
    pthread_mutex_destroy (&s.mtx);
}