互斥锁 / 什么是被锁定的互斥锁数据
mutex / what is the mutex data being locked?
#include <pthread.h>
#include <time.h>
#include "errors.h"
typedef struct alarm_tag {
struct alarm_tag *link;
int seconds;
time_t time; /* seconds from EPOCH */
char message[64];
} alarm_t;
pthread_mutex_t alarm_mutex = PTHREAD_MUTEX_INITIALIZER;
alarm_t *alarm_list = NULL;
void *alarm_thread (void *arg)
{
alarm_t *alarm;
int sleep_time;
time_t now;
int status;
while (1) {
status = pthread_mutex_lock (&alarm_mutex);
if (status != 0)
err_abort (status, "Lock mutex");
alarm = alarm_list;
/*
* If the alarm list is empty, wait for one second. This
* allows the main thread to run, and read another
* command. If the list is not empty, remove the first
* item. Compute the number of seconds to wait -- if the
* result is less than 0 (the time has passed), then set
* the sleep_time to 0.
*/
if (alarm == NULL)
sleep_time = 1;
else {
alarm_list = alarm->link;
now = time (NULL);
if (alarm->time <= now)
sleep_time = 0;
else
sleep_time = alarm->time - now;
#ifdef DEBUG
printf ("[waiting: %d(%d)"%s"]n", alarm->time,
sleep_time, alarm->message);
#endif
}
/*
* Unlock the mutex before waiting, so that the main
* thread can lock it to insert a new alarm request. If
* the sleep_time is 0, then call sched_yield, giving
* the main thread a chance to run if it has been
* readied by user input, without delaying the message
* if there's no input.
*/
status = pthread_mutex_unlock (&alarm_mutex);
if (status != 0)
err_abort (status, "Unlock mutex");
if (sleep_time > 0)
sleep (sleep_time);
else
sched_yield ();
/*
* If a timer expired, print the message and free the
* structure.
*/
if (alarm != NULL) {
printf ("(%d) %sn", alarm->seconds, alarm->message);
free (alarm);
}
}
}
int main (int argc, char *argv[])
{
int status;
char line[128];
alarm_t *alarm, **last, *next;
pthread_t thread;
status = pthread_create (
&thread, NULL, alarm_thread, NULL);
if (status != 0)
err_abort (status, "Create alarm thread");
while (1) {
printf ("alarm> ");
if (fgets (line, sizeof (line), stdin) == NULL) exit (0);
if (strlen (line) <= 1) continue;
alarm = (alarm_t*)malloc (sizeof (alarm_t));
if (alarm == NULL)
errno_abort ("Allocate alarm");
/*
* Parse input line into seconds (%d) and a message
* (%64[^n]), consisting of up to 64 characters
* separated from the seconds by whitespace.
*/
if (sscanf (line, "%d %64[^n]",
&alarm->seconds, alarm->message) < 2) {
fprintf (stderr, "Bad commandn");
free (alarm);
} else {
status = pthread_mutex_lock (&alarm_mutex);
if (status != 0)
err_abort (status, "Lock mutex");
alarm->time = time (NULL) + alarm->seconds;
/*
* Insert the new alarm into the list of alarms,
* sorted by expiration time.
*/
last = &alarm_list;
next = *last;
while (next != NULL) {
if (next->time >= alarm->time) {
alarm->link = next;
*last = alarm;
break;
}
last = &next->link;
next = next->link;
}
/*
* If we reached the end of the list, insert the new
* alarm there. ("next" is NULL, and "last" points
* to the link field of the last item, or to the
* list header).
*/
if (next == NULL) {
*last = alarm;
alarm->link = NULL;
}
#ifdef DEBUG
printf ("[list: ");
for (next = alarm_list; next != NULL; next = next->link)
printf ("%d(%d)["%s"] ", next->time,
next->time - time (NULL), next->message);
printf ("]n");
#endif
status = pthread_mutex_unlock (&alarm_mutex);
if (status != 0)
err_abort (status, "Unlock mutex");
}
}
}
嗨,这是我的代码,任何人都可以告诉我,因为互斥体没有在结构中声明。那么,当互斥锁锁定和解锁时,实际上正在更改哪些数据,有人可以启发我吗?
受互斥锁保护的这组数据在哪里?
互斥对象是 alarm_mutex
。受其"保护"的数据不必在代码中明确提及;就像在中一样,不需要有语义连接。互斥锁是一种低级线程原语,因此用户需要围绕它构建自己的逻辑。在您的情况下,内存中的一个位置用于阻止代码的其他部分(访问实际数据的部分)进行干扰。
这样想:std::atomic<int> x;
表示对其进行操作的原子性。 int x; mutex m;
要求访问x
的每一段代码都正确查看m
以确保程序的正确性。这个低级的 acess 就是我们在您的示例中看到的。
pthread_mutex_t alarm_mutex = PTHREAD_MUTEX_INITIALIZER;
创建一个共享互斥对象,用于锁定/解锁。
pthread_mutex_lock
会在互斥锁可用时立即锁定互斥锁。执行此行后,它对所有其他线程不可用。 pthread_mutex_unlock
解锁互斥锁,使其再次可用于其他线程(解锁另一个线程的pthread_mutex_lock
)
互斥锁不知道它在保护什么。程序员的工作是知道这一点,并且只在互斥锁锁定时更改它正在保护的数据。
在这种特定情况下,似乎alarm
列表是被锁定的数据。
相关文章:
- 防止主数据类型C++的隐式转换
- 用于访问容器<T>数据成员的正确 API
- C++ 11 中的锁定是否保证访问数据的新鲜度?
- 锁定的互斥锁是否保护condition_variable和数据?
- 我可以将部分数据用作锁定吗?
- 通知线程是否始终需要在修改期间锁定共享数据
- 试图更新和插入时,数据核心会被锁定
- 锁定免费的C++数据结构,不可能
- 在并发数据结构中,什么级别的锁定粒度是好的
- 在组合数据时不可能是恒定正确的,并且它是锁定的?
- 测试与C 原始数据类型上同步锁定的需求
- 互斥锁 / 什么是被锁定的互斥锁数据
- 我应该在多线程编程中始终锁定全局数据吗?为什么
- 为什么开发人员在多线程代码的读/写过程中锁定字长数据
- 是否可以使用互斥锁来锁定数据结构中的一个元素?
- 使用原子锁定自由的单生产者多消费者数据结构
- 树莓派从MPU6050+BMP180读取数据时锁定
- 在Linux上锁定对单个进程内数据访问的最快方法
- 如何锁定由属于两个不同类的两个线程修改的数据结构
- 是否有必要锁定STL容器以读取其数据?