pthreads: What happens if I create threads with same thread IDs? - pthreads

I am creating 2 threads with same thread IDs by doing this:
pthread_t pt;
int rc1, rc2, t1, t2;
t1 = 0;
t2 = 1;
rc1 = pthread_create(&pt, NULL, func(), (void*)&t1);
rc2 = pthread_create(&pt, NULL, func(), (void*)&t2);
func() just prints the passed parameter
What I found out is that output can be any of 0 then 1 or 1 then 0. What is really happening here? Is this case in anyway different from using two pthread_t values?

I am creating 2 threads with same thread IDs by doing this:
No you aren't. That's impossible.
The pthread_create function creates a new thread (with a unique ID) and stores the ID of the new thread in the pthread_t passed as the first argument. That argument is an out parameter, meaning the value of the pthread_t that you pass in is not used, a new value is stored to it for you to use after the call finishes.
What you're doing is creating two threads with different IDs, but you are overwriting the variable that holds the first ID when the second thread is created.
That means you only know one of the thread IDs, but there are still two different IDs.
If you don't know the ID of the first thread (because you overwrite the variable that stored the ID) then you can't join it, or detach it, or send it a signal.

What I found out is that output can be any of 0 then 1 or 1 then 0. What is really happening here? Is this case in anyway different from using two pthread_t values?
It won't make any difference. Using two thread IDs won't have any effect on the order of execution.
What happens if I create threads with same thread IDs?
If you don't have a thread ID then you can't join (using pthread_join()) with it or sending signals to it (using pthread_signal()), adjusting scheduling parameters (using pthread_setschedparam / pthread_getschedparam) etc. Other than that, it's fine.

Related

Reactor groupBy: What happens with remaining items after GroupedFlux is canceled?

I need to group infinite Flux by key with high cardinality.
For example:
group key is domain url
calls to one domain should be strictly sequential (next call happens after previous one is completed)
calls to different domains should be concurrent
time interval between items with same key (url) is unknown, but expected to have burst nature. Several items emitted in short period of time then long pause until next group.
queue
.groupBy(keyMapper, groupPrefetch)
.flatMap(
{ group ->
group.concatMap(
{ task -> makeSlowRemoteCall(task) },
0
)
.takeUntil { remoteCallResult -> remoteCallResult == DONE }
.timeout(groupTimeout, Mono.empty())
.then()
}
, concurrency
)
I cancel the group in two cases:
makeSlowRemoteCall() result indicates that with high probability there will be no new items in this group in near future.
Next item is not emitted during groupTimeout. I use timeout(timeout, fallback) variant to suppress TimeoutException and allow flatMap's inner publisher to complete successfully.
I want possible future items with same key to make new GroupedFlux and be processed with same flatMap inner pipeline.
But what happens if GroupedFlux has remaining unrequested items when I cancel it?
Does groupBy operator re-queue them into new group with same key or they are lost forever. If later what is the proper way to solve my problem. I am also not sure if I need to set concatMap() prefetch to 0 in this case.
I think groupBy() operator is not fit for my task with infinite source and a lot of groups. It makes infinite groups so it is necessary to somehow cancel idle groups downstream. But it is not possible to cancel GroupedFlux with guarantee that it has no unconsumed elements.
I think it will be great to have groupBy variant that emits finite groups.
Something like groupBy(keyMapper, boundryPredicate). When boundryPredicate returns true current group is complete and next element with same key will start new group.

stack data and restructure without using var to cases or casestovar in SPSS

I have the following situation: a loop (stack data) with only 1 index variable and with multiple items corresponding to the statements, as in the picture below (sorry it is Excel, but is the same as in SPSS):
stack data - cases on multiple lines, but never filling for 1 respondent all the columns
I want to reach to the following situation but without using casestovars to restructure, because that creates a lot of empty variables. I remember for older versions it was a command like Update, which was moving up the cases, to reach the following result:
reducing the cases per respondent
Like starting from this:
ID Index Q1_1 Q1_2 Q1_3 Q1_4 Q1_5 Q1_6
1 1 1 1
1 2 1 1
1 3 1 1
To reach to this:
ID Q1_1 Q1_2 Q1_3 Q1_4 Q1_5 Q1_6
1 1 1 1 1 1 1
But without using casestovars. Is there any command in SPSS syntax for this?
Thank you very much, have a nice day!
Not entirely sure how variable your data structure is likely to be in reality but if as demo'ed where you have only a single response for each q1_1 to q1_6 per respondent ID, then the below would be sufficient:
dataset declare dsAgg.
aggregate outfile="dsAgg" /break=respid /q1_1 to q1_6=max(q1_1 to q1_6).
Also not sure of the significance of duplicate index values within the same respondent IDs, if this was intended or not.
The following syntax could do the job -
* first we'll recreate your example data.
data list list/respid index q1_1 to q1_6.
begin data
1,1,1,,,,,
1,2,,2,,,,
1,3,,,1,,,
1,4,,,,2,,
1,5,,,,,1,
1,6,,,,,,2
2,1,3,,,,,
2,1,,4,,,,
2,2,,,5,,,
2,2,,,,4,,
2,3,,,,,3,
2,3,,,,,,2
end data.
* now to work: first thing is to make sure the data from each ID are together.
sort cases by respid index.
* the loop will fill down the data to the last line of each ID.
do repeat qq=q1_1 to q1_6.
if respid=lag(respid) and missing(qq) qq=lag(qq).
end repeat.
* the following lines will help recognize the last line for each ID and select it.
compute lineNR=$casenum.
aggregate /outfile=* mode=ADDVARIABLES/break=respid/MXlineNR=max(lineNR).
select if lineNR=MXlineNR.
exe.

Java 8- forEach method iterator behaviour

I recently started checking new Java 8 features.
I've come across this forEach iterator-which iterates over the Collection.
Let's take I've one ArrayList of type <Integer> having values= {1,2,3,4,5}
list.forEach(i -> System.out.println(i));
This statement iteates over a list and prints the values inside it.
I'd like to know How am I going to specify that I want it to iterate over some specific values only.
Like, I want it to start from 2nd value and iterate it till 2nd last value. or something like that- or on alternate elements.
How am I going to do that?
To iterate on a section of the original list, use the subList method:
list.subList(1, list.length()-1)
.stream() // This line is optional since List already has a foreach method taking a Consumer as parameter
.forEach(...);
This is the concept of streams. After one operation, the results of that operation become the input for the next.
So for your specific example, you can follow #Joni's command. But if you're asking in general, then you can create a filter to only get the values you want to loop over.
For example, if you only wanted to print the even numbers, you could create a filter on the streams before you forEached them. Like this:
List<Integer> intList = Arrays.asList(1,2,3,4,5);
intList.stream()
.filter(e -> (e & 1) == 0)
.forEach(System.out::println);
You can similarly pick out the stuff you want to loop over before reaching your terminal operation (in your case the forEach) on the stream. I suggest you read this stream tutorial to get a better idea of how they work: http://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/

Is Neo4j newsfeed flawed?

I am using this example, http://neo4j.com/docs/stable/cypher-cookbook-newsfeed.html, to maintain newsfeeds for my users. So I use the following to post a status update:
MATCH (me)
WHERE me.name='Bob'
OPTIONAL MATCH (me)-[r:STATUS]-(secondlatestupdate)
DELETE r
CREATE (me)-[:STATUS]->(latest_update { text:'Status',date:123 })
WITH latest_update, collect(secondlatestupdate) AS seconds
FOREACH (x IN seconds | CREATE (latest_update)-[:NEXT]->(x))
RETURN latest_update.text AS new_status
I encountered a severe flaw in this and don't know how to fix it. In a very rare scenario where two status updates are posted at the exactly same time (ex. 10ms apart), instead of replacing the current status, Neo4j creates two status updates. This leads to a much bigger problem where, the next updates are posted twice!
This looks like a race condition. To resolve that you basically need to make sure that at a given time only one transaction is modifying the status for this specific user.
Neo4j's Java API does have the ability to set locks to achieve this. Cypher doesn't have an explicit feature for this but you can e.g. remove a non-existing property to force a lock on the given node. With a lock in place concurrent transaction need to wait this the holder of the lock is finished with his transaction.
So grab a lock early in your statement:
MATCH (me)
WHERE me.name='Bob'
REMOVE me._not_existing // side effect: grab a lock early
WITH me
OPTIONAL MATCH (me)-[r:STATUS]-(secondlatestupdate)
DELETE r
CREATE (me)-[:STATUS]->(latest_update { text:'Status',date:123 })
WITH latest_update, collect(secondlatestupdate) AS seconds
FOREACH (x IN seconds | CREATE (latest_update)-[:NEXT]->(x))
RETURN latest_update.text AS new_status

Dart: DoubleLinkedQueue length after entry prepend

I'm manipulating entries inside a DoubleLinkedQueue via the DoubleLinkedQueueElement.append/prepend methods. This results in the new elements being inserted into the queue, but fails to update the length, and the toList() method results in an error being thrown.
I understand queues are only supposed to have elements added at the start/end, but it looks like the interface should allow for adding in the middle via the entries. I find it hard to believe such a common/well understood data structure would have a bug at this point - so am I using DoubleLinkedQueues incorrectly? Is there another data structure that I should be using? I'm looking to merge values from another iterable into my own sorted iterable - a SplayTreeSet might get me there in n log n time, but a simple merge should get me there in linear time...
Example of code that acts unexpectedly:
main() {
var q = new DoubleLinkedQueue<int>.from([1]);
q.firstEntry().prepend(0);
print('length: ${q.length}');
int i = 0;
for (var qi in q){
print('${i++}: $qi');
}
}
Output:
length: 1
0: 0
1: 1
It looks like the length getter is only pointing to an internal counter. This is done because counting the elements everytime might take very long for long lists.
The internal counter is only updated if you use the methods that directly operate on the list instead of using the prepend method of an element. In your example you should use q.addFirst(0); which results in the length being updates. The .prepend() method just inserts a new element and changes the pointer. Which results in correct traversation of the elements, but the counter is wrong anyway.
Unfortunately it looks like you cannot insert elements in the middle of the list, nor can you make the list recount the elements. You should consider creating a bug over at www.dartbug.com.
// Update:
toList() throws an error because there are more elements than length.

Resources