假设有一个生产者和多个消费者并且他们使用std::queue
,为了保护std::queue
中的数据,访问此std::queue
时必须使用互斥锁。
但是使用两个单独的锁呢?一个用于pop
,一个用于push
?我认为使用两个单独的锁可能会更快。
我查看了STL源代码。 std::queue
默认情况下由std::deque
实施。 pop_front()
和push_back()
使用两个单独的迭代器来访问数据,一个用于第一个元素,一个用于最后一个元素。
void push_front(const value_type& __x){
if (this->_M_impl._M_start._M_cur != this->_M_impl._M_start._M_first){
this->_M_impl.construct(this->_M_impl._M_start._M_ur - 1, __x);
} else {
_M_push_front_aux(__x);
}
}
void push_back(){
if (this->_M_impl._M_finish._M_cur != this->_M_impl._M_finish._M_first){
this->_M_impl.construct(this->_M_impl._M_finish._M_ur - 1, __x);
} else {
_M_pop_back_aux();
}
}
因此,当一个线程pop
队列时,另一个线程切入并尝试push_back
。因为这两个操作使用不同的迭代器,它们指向deque
的两个不同的端点,所以看起来这两个操作都可以正常吗?
答案 0 :(得分:1)
# -*- coding: utf-8 -*-
import iopro
from pandas import *
neuro = DataFrame()
cardio = DataFrame()
cancer = DataFrame()
addiction = DataFrame()
Adrugs = DataFrame()
Mdrugs = DataFrame()
Vdrugs = DataFrame()
all_drugs = DataFrame()
for year in xrange(2005,2013):
for month in xrange(1,13):
if year == 2005 and month < 7:
continue
filename = 'PATH/lmed_' + str(year) + '_mon'+ str(month) +'.txt'
adapter = iopro.text_adapter(filename,parser='csv',field_names=True,output='dataframe',delimiter='\t')
monthly = adapter[['LopNr','ATC','TKOST']][:]
monthly['year']=year
monthly['month']=month
neuro = neuro.append(monthly[(monthly.ATC.str.startswith('N')) & (~(monthly.TKOST.isnull()))])
cardio = cardio.append(monthly[(monthly.ATC.str.startswith('C')) & (~(monthly.TKOST.isnull()))])
cancer = cancer.append(monthly[(monthly.ATC.str.startswith('L')) & (~(monthly.TKOST.isnull()))])
addiction = addiction.append(monthly[(monthly.ATC.str.startswith('N07')) & (~(monthly.TKOST.isnull()))])
Adrugs = Adrugs.append(monthly[(monthly.ATC.str.startswith('A')) & (~(monthly.TKOST.isnull()))])
Mdrugs = Mdrugs.append(monthly[(monthly.ATC.str.startswith('M')) & (~(monthly.TKOST.isnull()))])
Vdrugs = Vdrugs.append(monthly[(monthly.ATC.str.startswith('V')) & (~(monthly.TKOST.isnull()))])
all_drugs = all_drugs.append(monthly[(~(monthly.TKOST.isnull()))])
del monthly
all_drugs = all_drugs.groupby(['LopNr','year','month']).sum()
all_drugs = all_drugs.astype(int,copy=False)
all_drugs.to_csv('PATH/monthly_all_drugs_costs.csv')
del all_drugs
neuro = neuro.groupby(['LopNr','year','month']).sum()
neuro = neuro.astype(int,copy=False)
neuro.to_csv('PATH/monthly_neuro_costs.csv')
del neuro
cardio = cardio.groupby(['LopNr','year','month']).sum()
cardio = cardio.astype(int,copy=False)
cardio.to_csv('PATH/monthly_cardio_costs.csv')
del cardio
cancer = cancer.groupby(['LopNr','year','month']).sum()
cancer = cancer.astype(int,copy=False)
cancer.to_csv('PATH/monthly_cancer_costs.csv')
del cancer
addiction = addiction.groupby(['LopNr','year','month']).sum()
addiction = addiction.astype(int,copy=False)
addiction.to_csv('PATH/monthly_addiction_costs.csv')
del addiction
Adrugs = Adrugs.groupby(['LopNr','year','month']).sum()
Adrugs = Adrugs.astype(int,copy=False)
Adrugs.to_csv('PATH/monthly_Adrugs_costs.csv')
del Adrugs
Mdrugs = Mdrugs.groupby(['LopNr','year','month']).sum()
Mdrugs = Mdrugs.astype(int,copy=False)
Mdrugs.to_csv('PATH/monthly_Mdrugs_costs.csv')
del Mdrugs
Vdrugs = Vdrugs.groupby(['LopNr','year','month']).sum()
Vdrugs = Vdrugs.astype(int,copy=False)
Vdrugs.to_csv('PATH/monthly_Vdrugs_costs.csv')
del Vdrugs
和select * from(
select a.*,'10' as srv from px_conversions_srv10 a
union all
select b.*,'12' as srv from px_conversions_srv12 b
) as ff where ff.adv_transaction_id in(1333764016);
update ff SET ff.`status`=8;
可能在内部访问不同的迭代器,但这就是整个抽象感:你不能确定它,而且不允许依赖它。
而且,正如评论中已经指出的那样,还有pop_front
,这是因为需要在push_back
中执行C ++ 11。为了满足这一要求,size
和O(1)
都需要改变一些内部存储,如果大小,那么你肯定会有竞争条件。
然后想想当你的队列变空时会发生什么......
简而言之:不要这样做。要在并发设置中使用push_back
,您需要一个互斥锁来保护它。
作为替代方案,您应该研究无锁数据结构。