这个问题相当笼统,广泛而深入。
因此,我的回答将使您初步了解多线程/多处理。
首先,我将问题分为两个主要问题:
1)单个进程内的线程同步。
2)单线程进程同步。
稍后您可以将 (1) 和 (2) 结合起来,不要忘记混合线程和分叉导致的特殊问题和副作用。
1。线程同步。
假设我们有一个具有 3 个(或 M,在一般情况下)线程 t1、t2 和 t3 的进程,它们应该以强顺序运行:t1、t2 和 t3。即使您完全按照这个顺序创建这些线程,也没有人能保证它们会按照这个顺序启动。您可以通过强制它们等待两个条件变量:c1 和 c2 来阻止 t2 和 t3 的执行。当 t1 和 t2 线程准备好时,上述条件变量将向 t2 和 t3 线程发出信号。 t1 线程将“解除阻塞”c1 变量,t2 线程将“解除阻塞”c2。
因此,您所需要的只是与两个(或 M-1)互斥锁关联的两个(或 M-1)条件变量和负责线程状态的两个(或 M-1)布尔值。这是一个简化的代码。虽然它可以工作(您可以使用 gcc -lpthread 编译它),但您的“真实”代码应该将变量组织成结构,检查错误等。
#include <pthread.h>
#include <stdio.h>
// These are mentioned mutexes, conditional variables and booleans.
// They are global, so any thread can access them.
pthread_mutex_t m1 = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t c1 = PTHREAD_COND_INITIALIZER;
int t1_is_ready = 0;
pthread_mutex_t m2 = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t c2 = PTHREAD_COND_INITIALIZER;
int t2_is_ready = 0;
// This function is invoked by the t1 thread.
// It does not depend on conditional variables and always is executed first.
// When it's ready it sets its ready status to one and signal to the thread t2
// via c2, that the status has changed.
void* t1_work(void* arg)
{
pthread_mutex_lock(&m1);
printf("thread t1 does its work\n");
t1_is_ready = 1;
pthread_mutex_unlock(&m1);
pthread_cond_signal(&c1);
pthread_exit(NULL);
}
// This function is invoked by the t2 thread.
// It is blocked until t1 setis is ready status to 1.
// Pay your attention how to wait on a conditional variable:
// with locked mutex and in a loop, to prevent spurious wakes up.
void* t2_work(void* arg)
{
pthread_mutex_lock(&m1);
while(t1_is_ready == 0)
{
pthread_cond_wait(&c1, &m1);
}
pthread_mutex_unlock(&m1);
pthread_mutex_lock(&m2);
printf("thread t2 does its work\n");
t2_is_ready = 1;
pthread_mutex_unlock(&m2);
pthread_cond_signal(&c2);
pthread_exit(NULL);
}
// This function is invoked by the t3 thread.
void* t3_work(void* arg)
{
pthread_mutex_lock(&m2);
while(t2_is_ready == 0)
{
pthread_cond_wait(&c2, &m2);
}
printf("thread t3 does its work\n");
pthread_mutex_unlock(&m2);
pthread_exit(NULL);
}
int main(void)
{
pthread_t t1;
pthread_t t2;
pthread_t t3;
pthread_create(&t1, NULL, t1_work, NULL);
pthread_create(&t2, NULL, t2_work, NULL);
pthread_create(&t3, NULL, t3_work, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_join(t3, NULL);
return 0;
}
2。进程同步
这是一篇不错的文章,其中包含进程同步的代码示例:
http://www.linuxdevcenter.com/pub/a/linux/2007/05/24/semaphores-in-linux.html?page=5
由于您计划通过 fork() 函数创建流程,因此它们将被称为“相关”。如果您有 3(或 N)个正在运行的进程创建 2(N-1)个信号量,以您同步线程的方式使用它们。