C处的线程同步

aqu*_*ini 1 c multithreading synchronization

我必须使用两个线程; 一个用于对矩阵进行各种操作,另一个用于监视矩阵运算过程中各个点的虚拟内存.使用全局状态变量'flag'需要此方法.

到目前为止,我有以下内容(为简洁而留下一些):

int flag = 0;

int allocate_matrices(int dimension)
{
    while (flag == 0) {} //busy wait while main prints memory state

    int *matrix = (int *) malloc(sizeof(int)*dimension*dimension);
    int *matrix2 = (int *) malloc(sizeof(int)*dimension*dimension);

    flag = 0;
    while (flag == 0) {} //busy wait while main prints memory state

    // more similar actions...
}

int memory_stats()
{
    while (flag == 0)
    { system("top"); flag = 1; }
}

int main()
{ //threads are created and joined for these two functions }
Run Code Online (Sandbox Code Playgroud)

正如您所料,system("top")调用发生一次,矩阵被分配,然后程序陷入无限循环.我觉得这是因为分配给memory_stats函数的线程已经完成了它的任务,所以flag永远不会再次更新.

这周围有优雅的方式吗?我知道我必须打印四次内存统计数据,所以我觉得我可以在memory_stats函数中编写四个while循环,忙于等待每个循环之间的全局标记,但这对我来说似乎很笨拙.任何帮助或指示将不胜感激.

cgo*_*gon 5

您可以使用互斥锁将其锁定.我假设你使用pthread.

pthread_mutex_t mutex;

pthread_mutex_lock(&mutex);
flag=1;
pthread_mutex_unlock (&mutex);
Run Code Online (Sandbox Code Playgroud)

这是一个关于pthreads,互斥体和其他东西的非常好的教程:https://computing.llnl.gov/tutorials/pthreads/


Ale*_*nze 5

挂起的一个可能原因是,它flag是一个常规变量,并且编译器发现它永远不会在此内部flag = 0;和之间设置为非零值.因此它"认为"变量保持为0并且循环变为无限.编译器完全忘记了你的线程.while (flag == 0) {}whileallocate_matrices()

您可以定义flagvolatile防止上述情况发生,但添加后您可能会遇到其他问题volatile.首先,volatile不保证变量修改的原子性.

另一个问题是,如果编译器看到一个没有副作用的无限循环,它可能被认为是未定义的行为,任何事情都可能发生,或者至少不是你想的那样,也就是这个.

您需要使用正确的同步原语,如互斥锁.