2015年08月

Share variable between multiple threads

I'm creating simulation of a train station. Train information is read from a file. Each line of the file represents a train and each train gets its own thread. The main track of the train station can only hold 1 train at a time. Here is my code:



#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <readline/readline.h>
#include <unistd.h>

pthread_mutex_t main_track_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t main_track_condition_var = PTHREAD_COND_INITIALIZER;
int main_track_status = 0;

void *train_function(void *args) {
/* Parse train information */
int line_number = atoi(strtok(args, ":,"));
char *priority_direction = strtok(NULL,":,");
int loading_time = atoi(strtok(NULL, ":,"));
int crossing_time = atoi(strtok(NULL, ":,"));

/* Load train */
sleep(loading_time/10);
printf("Train %d is ready to go %s\n",line_number,priority_direction);

/* If the main track is currently in use, wait for it to become available */
while(main_track_status)
pthread_cond_wait(&main_track_condition_var, &main_track_mutex);

/* Use the main track */
pthread_mutex_lock(&main_track_mutex);
main_track_status = 1;
printf("Train %d is ON the main track going %s\n",line_number,priority_direction);
sleep(crossing_time/10);
main_track_status = 0;

/* Notify other trains main track is empty */
pthread_mutex_unlock(&main_track_mutex);
pthread_cond_signal(&main_track_condition_var);
printf("Train %d is OFF the main track after going %s\n",line_number,priority_direction);

pthread_exit(0);
}

int main() {
FILE *ptr_file;
char buff[10];
int train_count = 0;
char *train;
char line[15];
pthread_t trains[3];

ptr_file = fopen("./trains.txt", "r");

if (!ptr_file)
{
perror("fopen for trains.txt failed");
exit(EXIT_FAILURE);
}

/* Create train for each line of file */
while (fgets(buff,10, ptr_file)!=NULL) {
train = (char*)malloc(10 * sizeof(char));

/* Include line number from file in train information */
sprintf(line, "%d:", train_count);
strcat(line, buff);
strcpy(train, line);

if(pthread_create(&trains[train_count], NULL, &train_function, (void *) train))
{
perror("pthread create failed");
exit(EXIT_FAILURE);
}
train_count++;
}
fclose(ptr_file);

/* Wait for all trains to leave the station */
for (int x = 0; x < train_count; x++) {
pthread_join(trains[x], NULL);
}

free(train);
exit(EXIT_SUCCESS);
}


The trains input file:



e:10,6
W:5,7
E:3,10


The output of the program is:



Train 1 is ready to go W
Train 1 is ON the main track going W
Train 1 is OFF the main track after going W
Train 2 is ready to go E
Train 2 is ON the main track going E
Train 0 is ready to go e
Train 2 is OFF the main track after going E


I think my error lies in the train_function. As you can see, train 0 never gets access to the main track. I must be misunderstanding how threads are awoken with condition variables and am getting stuck in a deadlock. What am I missing?



Answers

Yes, you have a slight misunderstanding of pthread_cond_wait. The man page says:




The pthread_cond_timedwait() and pthread_cond_wait() functions shall
block on a condition variable. They shall be called with mutex locked
by the calling thread or undefined behavior results.



These functions atomically release mutex and cause the calling thread
to block on the condition variable cond;




So you need to lock before calling the pthread_cond_wait. That is, your code should be:



/* If the main track is currently in use, wait for it to become available */
pthread_mutex_lock(&main_track_mutex); /* SHOULD LOCK HERE */
while(main_track_status)
pthread_cond_wait(&main_track_condition_var, &main_track_mutex);

/* Use the main track */
//pthread_mutex_lock(&main_track_mutex); /* INCORRECT */
//<..SNIP..>
pthread_mutex_unlock(&main_track_mutex);
pthread_cond_signal(&main_track_condition_var);




jquery — Have collapsing div start collapsed

I have a collapsing div that works perfectly fine but it starts expanded.



How can I get the div to start collapsed?



Also, how can I get the "Learn More" button to change its text to "Hide" when the div has been expanded?





$(function(){
$('a.togglebtn').click(function(){
$('#myContent3').stop().slideToggle(500);
return false;
});
});

<div>
<a class="lead p-color learn-button togglebtn">
<small>
<span class="glyphicon glyphicon-plus">
</span> Learn More
</small>
</a>
</div>

<div id="myContent" class="row row-offset" style="margin: 0 30px">
<div class="col-xs-6 col-md-4">
<div class="lead caption text-center">
<h3 class="h-color">Profile</h3>
</div>
<div class="thumbnail">
<img style="height: 100px; width: auto;" class="img-circle" src="images/logo-bunny.png" alt="Thumbnail">
</div>
<div class="lead caption">
<p class="p-color"><small>Some sample text. Some sample text.</small></p>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


Answers

Slightly changed your code. Try this.

<div>
<a class="lead p-color learn-button togglebtn">
<small>
<span class="glyphicon glyphicon-plus">
</span> <span id="toggleText">Learn More</span>
</small>
</a>
</div>

<div id="myContent" class="row row-offset" style="margin: 0 30px">
<div class="col-xs-6 col-md-4">
<div class="lead caption text-center">
<h3 class="h-color">Profile</h3>
</div>
<div class="thumbnail">
<img style="height: 100px; width: auto;" class="img-circle" src="images/logo-bunny.png" alt="Thumbnail">
</div>
<div class="lead caption">
<p class="p-color"><small>Some sample text. Some sample text.</small></p>
</div>
</div>
</div>


$(function(){
$('a.togglebtn').click(function(){
if($("#toggleText").text()=="Learn More"){
$("#toggleText").html("Hide")}
else {$("#toggleText").html("Learn More")}
$('#myContent').stop().slideToggle(500);
return false;
});
});


#myContent{display:none;}


Hope this is the one you have expected.



Answers

you need to do this:



<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Collapsible Div</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
</head>
<body>
<div>
<a class="lead p-color learn-button togglebtn" data-toggle="collapse" data-target="#myContent">
<small>
<span class="glyphicon glyphicon-plus">
</span> Learn More
</small>
</a>
</div>

<div id="myContent" class="row row-offset collapse" style="margin: 0 30px">
<div class="col-xs-6 col-md-4">
<div class="lead caption text-center">
<h3 class="h-color">Profile</h3>
</div>
<div class="thumbnail">
<img style="height: 100px; width: auto;" class="img-circle" src="http://placehold.it/100x150" alt="Thumbnail">
</div>
<div class="lead caption">
<p class="p-color"><small>Some sample text. Some sample text.</small></p>
</div>
</div>
</div>
</body>
</html>


Just add data-toggle="collapse" and a data-target to element <a> The data-target attribute takes your usual css selectors (id, class, name etc). The .collapse is set to "" which starts collapsed.



Check here for more info: w3schools





Smallest set of multi-sets that together contains all numbers from 1 to N

Lets assume that we have only integer numbers which values are in range 1 to N. Next we will split them into K-element multi-sets. How would you find such set which contains smallest possible number of those multi-sets yet sum of this multi-set contains all numbers from 1 to N? In case of ambiguity answer will be any set that matches criteria (first found).



For instance, we have N = 9, K = 3



(1,2,3)(4,5,6)(7,8,8)(8,7,6)(1,9,2)(4,4,3)



Smallest number of multi-sets that contains all the numbers from 1 to 9 is equal to 4 and can be either (1,2,3)(4,5,6)(7,8,8)(1,9,2) or (1,2,3)(4,5,6)(8,7,6)(1,9,2).



Any idea for efficient algorithm to find such set?



PS
After writing an answer I found yet another 4 element set: (4,5,6)(1,9,2)(4,4,3)(7,8,8) or (4,5,6)(1,9,2)(4,4,3)(8,7,6) But as I said algorithm finding any minimum set would be fine.



Answers

Your question is a restricted version the classic Set Covering problem, but it still easy to show that it is NP-Hard.



Any approximation technique for this problem would be reasonable here. In particular, the greedy solution of choosing the next subset covering the most uncovered items - is esp. easy to implement.



Answers

This problem, as @Ami Tavroy said, is NP-hard by reduction to 3-dimensional matching (here).



To do the reduction, note the restricted decision variant of 3-dimensional matching when it reduces to a exact cover (here):




...given a set T and an integer k, decide whether there exists a
3-dimensional matching M ⊆ T with |M| ≥ k. ... The problem is
NP-complete even in the special case that k = |X| = |Y| =
|Z|.1[4][5] In this case, a 3-dimensional (dominating) matching is
not only a set packing but also an exact cover: the set M covers each
element of X, Y, and Z exactly once.[6]




This variant can be solved in P if you can solve the other question in P - you can produce all the triples in O(N ^ 3) time and then do set cover, and check if K = N / 3 or not. Thus by reduction, the original questions is also NP-hard.





How to split circle in buttons

I'm trying to split a circle with gradient Color in four clickable buttons, as I show on the picture. Does anyone know how to do that without using images? I've tried many different approaches, but I couldn't find any valid solution.







Filter mysql data for chart visualisation

On my portal I have a chart (devexpress) which uses an API to load JSON records.



In my example I have a sensor which inserts a new record into the database every 60 seconds with following fields: id, serialnumber, tag_id, timestamp, value. So on any one day I have about 1440 datapoints in the database.



On the chart I have a datepicker, which I can choose a specific time range. Now when I choose, "last month", my AJAX call will send the 2 timestamps (now and now - 1 month) to the API.



So I will get 30 x 1440 records for my chart. This is too many. Now I need a solution, that when I chose a 7 day period, I get one record for each hour or when I chose last month I get just one record every day as an average of all the records for the day.



My SQL query on the API is:



SELECT * FROM `records` WHERE `timestamp` BETWEEN "' . $posts['from'] . '" AND "' . $posts['to'] . '"'


Answers

You need to add GROUP BY to your sql. In following example you will find exact solution for your needs.



Grouping timestamps in MySQL with PHP





↑このページのトップヘ