我对 pthreads 完全陌生,在我看过的所有网站上似乎都有很多不必要的信息。
我有两个函数,我们暂时称它们为 X 和 Y,它们都适用于内存中的块。如果一个线程正在运行 XI 不希望任何其他线程在同一块上调用 X 或 Y,我如何确保这永远不会发生?
我是否需要对某些块值的功能进行互斥锁?
您将需要使用互斥锁。
你不应该锁定代码,你应该锁定数据。为每个块创建一个互斥锁,并在函数对块进行操作时将其锁定,然后在完成时将其解锁。
互斥锁是由 pthread.h、pthread_mutex_t 定义的类型。提供了锁定和解锁互斥锁的函数。这些函数确保一次只有一个线程可以获得锁(如果您只是使用一个变量来指示您的块正在被使用,那么您将遇到该变量而不是块的并发问题)。
网上有很多教程。谷歌“pthread 教程”,你应该找到足够的东西让自己开始。
您使用互斥锁锁定资源(在本例中为内存块)。或者,您可以仅锁定读取/更新该内存区域的函数代码部分。这称为临界区,需要不同的编码方法。这意味着您的线程可以自由操作,除非它们遇到与资源交互的部分。
第一种方法更容易实现——对整个函数 X 或 Y 来说只是全有或全无的方法。
也许一些演示代码是有序的。假设你有一个像这样的块头:
struct block {
void *data;
size_t len;
};
您可以通过在此结构中添加互斥变量来保护块:
struct block {
void *data;
size_t len;
pthread_mutex_t lock;
};
然后你需要更新这个结构的初始化函数来初始化锁:
struct block *new_block(size_t len)
{
struct block *b = malloc(sizeof *b);
b->data = malloc(len);
b->len = len;
pthread_mutex_init(&b->lock, NULL);
return b;
}
然后 X 和 Y 函数(以及任何其他读取或写入块的函数)需要获取锁并在退出时释放它:
int x(struct block *b)
{
int retval;
pthread_mutex_lock(&b->lock);
/* code */
pthread_mutex_unlock(&b->lock);
return retval;
}
int y(struct block *b)
{
int retval;
pthread_mutex_lock(&b->lock);
/* code */
pthread_mutex_unlock(&b->lock);
return retval;
}
即使在错误返回路径中,您也需要小心确保解锁互斥锁。
Multi-threaded programming is really better resolved using in higher level languages. Some things are difficult to understand in C, and, in my opinion, mutli-threading is one of them. I've found Java gave me a better feel for the issues and problems. It has easier to understand concepts and easier to read documentation. A C++ framework such as Poco or Qt would also be better if Java is not your thing.
As others have said, conceptually you want to lock resources (in your case a section of memory). Semaphores, as a concept, fit this problem much better than mutex does. I would research semaphores and just think of mutexes as a building block of semaphores. If you ask me, a mutex is a poorly named binary semaphore.