【发布时间】:2020-12-07 00:40:26
【问题描述】:
我正在处理一个更大的项目,其中包括两个线程,其中一个数据库在它们之间共享。一个线程的工作是对每个活动元素计时器进行倒计时,当该元素的计时器为零时,它应该将其设置为非活动并将其归零。
主线程只是在以某种方式操作活动元素的其他变量。
我不知道如何同步这些线程,尤其是当计时器达到零时计时器线程清理数据库元素时。现在我认为在main() 中的while(1) 循环中解锁和锁定mutex 之间的时间可能太快了?
如果定时器线程正在等待mutex在pthread_mutex_lock()解锁;它在main() 中解锁,我们是否知道计时器线程 将是下一个锁定mutex 的线程,或者main() 可能会如此之快以至于它再次锁定它pthread_mutex_unlock() 和 pthread_mutex_lock() 之间没有任务?
我没有使用条件变量的经验,这可能是个好主意吗?
这是我更大的项目的一个最小工作示例。
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <time.h>
#define NUM_COMPUTER 10
typedef struct computer
{
unsigned int active;
unsigned int timer;
int x;
}computer_t;
/**
* Function declarations
*/
void activate(computer_t* comp);
void* timerFunction(void* args);
/**
* Global variables
*/
computer_t database[NUM_COMPUTER];
pthread_mutex_t mutex;
main() 函数
/**
* Main
*/
int main(void)
{
memset(database, 0, sizeof database);
// Initialize some database elements
activate(database);
database[0].x = 5;
activate(database + 3);
database[3].x = 23;
activate(database + 9);
database[9].x = -7;
pthread_t timer_thread;
pthread_create(&timer_thread, NULL, timerFunction, NULL);
while(1)
{
/**
* MAY PROBLEMS OCCUR HERE? UNLOCKING AND LOCKING ALMOST DIRECTLY
*/
// ************* LOCK *************
pthread_mutex_lock(&mutex);
/**
* Manipulate struct members
*/
for (int i = 0; i < NUM_COMPUTER; i++)
{
if (database[i].active)
{
database[i].x += 1;
}
}
// ************* UNLOCK *************
pthread_mutex_unlock(&mutex);
}
return 0;
}
额外功能
void activate(computer_t* comp)
{
comp->active = 1;
comp->timer = 100;
}
void* timerFunction(void* args)
{
struct timespec ts;
// Sleep interval before checking database again
ts.tv_sec = 1;
ts.tv_nsec = 0;
while(1)
{
// ************* LOCK *************
pthread_mutex_lock(&mutex);
/**
* Go through every database index
*/
for (int index = 0; index < NUM_COMPUTER; index++)
{
if (database[index].active)
{
if (database[index].timer > 0)
{
database[index].timer--;
}
else
{
/**
* Clean up database index
*/
memset(database + index, 0, sizeof database);
}
}
}
// ************* UNLOCK *************
pthread_mutex_unlock(&mutex);
/**
* Sleep 1 sec before checking database again
*/
nanosleep(&ts, NULL);
}
}
【问题讨论】:
-
您的 x 计数器不太可能达到 0,因为您的主线程正在使用 100% cpu 负载更新该值,因为没有睡眠。在等待一秒钟以减少计时器线程中的一个值时,该值在您的主线程中增加了数千次。
-
@MatzZze 没错,但是 timerThread 还会每秒递减一次吗?
-
是的,它会每秒递减一次
-
@MatzZze 即:如果 线程一 已锁定
mutex并且 线程二 停止在pthread_mutex_lock()和 线程一解锁mutex。 线程一总是会赢得mutex,即使线程二在解锁后直接尝试锁定它?
标签: c synchronization pthreads mutex race-condition