timer_settime()
每秒构建一次计时器。信号处理程序是traffic_measurement_handler
。 traffic_measurement_handler
是否在新线程中运行?当处理程序运行时如何让callback
停止?
#define CLOCKID CLOCK_REALTIME
#define SIG SIGUSR1
timer_t timerid;
int main(void)
{
..
build_timer();
pcap_loop(pcap_handle, -1, callback, NULL);
}
void callback() // callback of Libpcap API: pcap_loop()
{
detect_network_traffic(); // stop when timer expires, and then continue
// to run when traffic_measurement_handler has finished.
}
// timer handler runs every second to update database
void traffic_measurement_handler()
{
.. // This block will fetch global variables, so I want to
// let callback stop when this handler is running.
// rebuild the timer
build_timer();
}
// set timer
void build_timer()
{
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = traffic_measurement_handler;
sigemptyset(&sa.sa_mask);
sigaction(SIG, &sa, NULL);
sev.sigev_notify = SIGEV_SIGNAL;
sev.sigev_signo = SIG;
sev.sigev_value.sival_ptr = &timerid;
timer_create(CLOCKID, &sev, &timerid);
its.it_value.tv_sec = 1;
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = its.it_value.tv_sec;
its.it_interval.tv_nsec = its.it_value.tv_nsec;
timer_settime(timerid, 0, &its, NULL);
}
信号处理程序在只存在一个线程的过程中是否安全?
已添加:第二版本 这是对的吗?
pthread_t thread_global;
int main(void)
{
// register SIGUSR1 handler
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = traffic_measurement_handler;
sigemptyset(&sa.sa_mask);
sigaction(SIG, &sa, NULL);
pthread_create(&thread1, NULL, processing_thread, (void *) thread_id1);
pthread_create(&thread2, NULL, timer_thread, (void *) thread_id2);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
}
void *processing_thread(void *thread_id)
{
pcap_loop(pcap_handle, -1, callback, NULL);
}
void callback() // callback of Libpcap API: pcap_loop()
{
thread_global = pthread_self();
detect_network_traffic(); // stop when SIGUSR1 is caught, and then continue
// to run when traffic_measurement_handler has finished.
}
//update database every second when SIGUSR1 is caught
void traffic_measurement_handler()
{
..
}
//This thread is used to notify updating database every second.
void *timer_thread(void *thread_id)
{
for (; ;) {
sleep(1);
pthread_kill(thread_global, SIGUSR1);
}
}
答案 0 :(得分:1)
要将计时器处理程序作为线程模式运行,您必须修改timer_create
的值
请阅读 SIGEV_NONE
Don't asynchronously notify when the timer expires. Progress
of the timer can be monitored using timer_gettime(2).
SIGEV_SIGNAL
Upon timer expiration, generate the signal sigev_signo for the
process. See sigevent(7) for general details. The si_code
field of the siginfo_t structure will be set to SI_TIMER. At
any point in time, at most one signal is queued to the process
for a given timer; see timer_getoverrun(2) for more details.
SIGEV_THREAD
Upon timer expiration, invoke sigev_notify_function as if it
were the start function of a new thread. See sigevent(7) for
details.
SIGEV_THREAD_ID (Linux-specific)
As for SIGEV_SIGNAL, but the signal is targeted at the thread
whose ID is given in sigev_notify_thread_id, which must be a
thread in the same process as the caller. The
sigev_notify_thread_id field specifies a kernel thread ID,
that is, the value returned by clone(2) or gettid(2). This
flag is intended only for use by threading libraries.
Specifying sevp as NULL is equivalent to specifying a pointer to a
sigevent structure in which sigev_notify is SIGEV_SIGNAL, sigev_signo
is SIGALRM, and sigev_value.sival_int is the timer ID.
sevp.sigev_notify字段可以包含以下值:
timer_settime
的手册页
此处pcap_loop
将充当不同的主题,因为protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.graph_budget);
pieChart = (PieChart) findViewById(R.id.pie_budget);
setDataChart();
}
public void setDataChart(){
DBHelper db = new DBHelper (getApplicationContext());
List<Budget_PieChartList> names = db.getListPieChart();
pieChart.setRotationEnabled(true);
pieChart.animateXY(1000, 1000);
pieChart.setHoleRadius(36f);
pieChart.setDescription(null);
ArrayList<PieEntry> yVals = new ArrayList<>();
ArrayList<String> xVals = new ArrayList<>();
ArrayList<Integer> colors = new ArrayList<Integer>();
for (int c : ColorTemplate.VORDIPLOM_COLORS)
colors.add(c);
for (int c : ColorTemplate.JOYFUL_COLORS)
colors.add(c);
for (int c : ColorTemplate.COLORFUL_COLORS)
colors.add(c);
for (int c : ColorTemplate.LIBERTY_COLORS)
colors.add(c);
for (int c : ColorTemplate.PASTEL_COLORS)
colors.add(c);
colors.add(ColorTemplate.getHoloBlue());
float total_amount = db.getTotalAmount();
for(int index = 0; index<names.size(); index++){
float amount = (names.get(index).getAmount()/total_amount)*100f;
yVals.add(new PieEntry(amount, index));
xVals.add(names.get(index).getName());
}
PieDataSet dataSet = new PieDataSet(yVals, "");
dataSet.setSliceSpace(3f);
dataSet.setSelectionShift(5f);
dataSet.setColors(colors);
PieData dataPie = new PieData(dataSet);
dataPie.setValueFormatter(new PercentFormatter());
dataPie.setValueTextSize(12f);
dataPie.setValueTextColor(Color.BLACK);
Legend legend = pieChart.getLegend();
legend.setForm(Legend.LegendForm.CIRCLE);
legend.setPosition(Legend.LegendPosition.LEFT_OF_CHART);
pieChart.setData(dataPie);
pieChart.highlightValues(null);
pieChart.invalidate();
}
会创建一个新主题。
答案 1 :(得分:1)
traffic_measurement_handler
是否在新线程中运行?
在POSIX threads中sigev_notify = SIGEV_SIGNAL
时,由于信号没有创建新线程。因此,在您的代码中,您不会创建新线程。
如何在处理程序运行时让回调停止?
您可以将信号设置为由运行回调的同一线程处理。
POSIX.1区分了作为整体指向进程的信号的概念和指向单个线程的信号。