gcc 4.7.2
c89
您好,
我只是想知道如何为以下代码片段应用互斥锁。
您是否应该遵循任何规则,因为我不想锁定,因为这会阻止此函数中的其他线程。因为这会让事情变慢。
我正在使用以下CFLAGS进行编译:
-Wall -Wextra -g -m32 -O2 -D_DEBUG -D_THREAD_SAFE -D_REENTRANT -D_LARGEFILE64_SOURCE
代码段
static void* APR_THREAD_FUNC timeout_duration(apr_thread_t *thd, void *data)
{
apr_status_t rv = 0;
channel_t *channel = NULL;
/*
APPLY LOCK HERE
*/
channel = (channel_t*)data;
/* simulate some work */
apr_sleep(5000000);
LOG_INFO("Channel id [ %d ] Channel name [ %s ] Delay time [ %d ]",
channel->id,
channel->name,
(apr_int32_t)channel->delay_time);
/*
UNLOCK HERE
*/
return NULL;
}
我将通道作为传递给入口函数的数据传递。但是,这不是一个副本,所以我真的不需要担心吗?
答案 0 :(得分:3)
规则是:
1)锁定保护数据而不是代码。当数据受锁保护时,访问该数据的代码必须获取数据的锁定。
2)应尽可能晚地获取锁,并尽早释放。这可以包括将工作从关键部分内部转移到临界部分之外。
3)仅读取(未修改)的数据不需要锁定。这包括"Channel id [ %d ] ..."
格式字符串(应将其视为常量)等内容。
4)只能由一个线程访问的数据不需要锁定。这包括函数参数和局部变量等内容。
5)细粒度锁定优于粗粒度锁定。例如,通常您可以将大型数据结构拆分为许多具有多个锁的较小结构,而不是将一个大型数据结构与一个锁分开。
6)如果任何代码一次需要多个锁,则需要定义“锁定顺序”。例如,如果一个线程获得锁A然后锁B,那么一些工作然后释放锁;如果另一个线程获得锁B然后锁定A,有些工作然后释放锁;然后你可以得到死锁(每个线程有一个锁,但需要两个继续)。定义“锁定顺序”(例如,在锁B之前必须获取锁A)可以防止出现这种错误。
对于您的代码,前几行根本不需要锁,因为它们只访问函数参数和局部变量(规则4)。 void *data
指向的数据可能需要也可能不需要锁定,具体取决于它是什么 - 例如如果每个线程都有自己独立的数据(规则4),或者只读取该数据(规则3),则不需要锁定。对于LOG_INFO()
函数,在您发布的代码中不需要额外的锁定(如果存在void *data
锁定除外),但它可能有自己的内部锁定(例如,用于保护共享日志)。 / p>
对于规则2的示例,如果LOCK_INFO
需要一点时间,您的代码可能会执行类似这样的操作以便先释放第一个锁:
temp_ID = channel->id;
temp_name = strdup(channel->name); // Should check for NULL!
temp_delay = channel->delay_time;
/*
UNLOCK HERE
*/
LOG_INFO("Channel id [ %d ] Channel name [ %s ] Delay time [ %d ]",
temp_ID,
temp_name,
temp_delay);
free(temp_name);
另请注意,如果LOCK_INFO()
使用锁定,则先发布第一个锁定也会对规则6有所帮助。
答案 1 :(得分:2)
如果要在互斥锁解锁时读取此通道,请使用pthread_mutex_trylock()而不是pthread_mutex_lock()。它做的相同,但pthread_mutex_trylock()不是blocant, 基于它的返回值,你可以做到:
if (pthread_mutex_trylock(your_mutex))
{
//Read the data.
}
答案 2 :(得分:1)
不,它不是副本,data
实际上只是数据的指针,因此,您的线程和调用者上下文可以访问此相同的数据。现在,如果您可以保证(线程和调用者上下文)不会同时触及数据,则不需要在线程函数中锁定。
答案 3 :(得分:1)
您肯定需要担心,因为data
是指向您的实际channel_t
数据的指针。
但是,如果你想使用线程并行工作,那么拥有一个很长的工作时间并保持锁定会毫无意义。更精细的谷物锁定会更好 - 但这当然假设完成的整体操作可以分成多个部分,使数据保持一致状态。