I'm doing smth like:
Iterator<String> iterator = requestList.iterator()
(1..threadCount).each {
Thread.start {
while(iterator.hasNext()) {
log.info iterator.next()
Thread.sleep(50)
}
}
}
Given that threadCount = 10 and requestList is ~115, I expect all threads to output all the list, each time asking iterator to give them next.
However, I hardly even get 10 logs, usually 8.
Everything is done inside SoapUI groovy script step, instead of log.info I actually plan triggering a REST request with number N.
What am I doing wrong with these threads?
UPD
Okay, did smth stupid like this, to test (and avoid using one array):
def array1 = all[0..5]
def array2 = all[6..11]
Thread.start{
for(String r: array1) {
log.info r
}
}
Thread.start{
for(String r: array2) {
log.info r
}
}
And now I have no output at all or one log at most, though I expect 12.
How do I create threads that will output data simultaneously?
EVEN MORE
def threadCount=10
(0..threadCount).each { n ->
Thread.start {
(1..10).each {
log.info "thread"+n+" says| "+it
}
}
}
Output is:
thread0 says| 1
thread3 says| 1
thread8 says| 1
thread2 says| 1
thread1 says| 1
thread9 says| 1
thread7 says| 1
thread5 says| 1
thread4 says| 1
thread0 says| 2
And nothing more. Again, what's wrong with me or groovy? (hope groovy is fine)
In the end, problem is that SoapUI kills main thread before all threads have an opportunity to grab their next number.
A quick way to live with this is to add sleep to main method
Related
Im trying to count to 200000 in four threads, I want to count with the first both
threads to 200_000 and subtract after counting of the both first.
I know I can do it with join, but when im starting join it doesn't count because of the add function (counter++)
It look like this:
val s = Semaphore(1)
var count = 0
thread{
repeat(100_000){
s.acquire()
add()
s.release()
println("${Thread.currentThread().name} :$count")
}
}
thread{
repeat(100_000){
s.acquire()
subtract()
s.release()
println("${Thread.currentThread().name} :$count")
}
}
fun add(){
count++
}
fun subtract(){
count--
}
The functions do only add/subtract for the counter variable above the Threads
In a loop I create 4 closures and add them to a list:
closureList = []
for (int i=0; i<4; i++) {
def cl = {
def A=i;
}
closureList.add(cl)
}
closureList.each() {print it.call()println "";};
This results in the following output:
4
4
4
4
But I would have expected 0,1,2,3 instead. Why does the 4 closures have the same value for A?
Yeah, this catches people out, the free variable i is getting bound to the last value in the for loop, not the value at the time the closure was created.
You can either, change the loop into a closure based call:
closureList = (0..<4).collect { i ->
{ ->
def a = i
}
}
closureList.each { println it() }
Or create an extra variable that gets re-set every time round the loop, and use that:
closureList = []
for( i in (0..<4) ) {
int j = i
closureList << { ->
def a = j
}
}
closureList.each { println it() }
In both of these variants the variable closed by the closure is created afresh each time round the loop, so you get the result you'd expect
I try to check if a graph is hamiltonian by generating and checking for random paths on it but the script ends without reaching it's result. I also keep a mutex made of a semaphore for the result and this condition is well preserved until the script returns with null and not reaching the final prints.
def pathFinder(){
def permutation = []
for (int i = 1; i <= noOfNodes; i++)
permutation.push(i)
while(true){
if( mutex.tryAcquire(MAX_TIME,TimeUnit.MILLISECONDS) )
{ println "mutex acquired"
if(finalFound){
//check if another thread solved the problem
mutex.release()
println "mutex released - solution found"
break
}
println "solution not found"
//release the lock while checking the permutation
mutex.release()
println "mutex released for others to start looking"
permutation = permutation.sort { new Random().nextInt() }
println "permutation generated: "+permutation
if(isPathHamiltonian(permutation)){
if(mutex.tryAcquire(MAX_TIME,TimeUnit.MILLISECONDS))
{
println "mutex acquired for result"
finalPermutation = permutation
finalFound = true
mutex.release()
println "mutex for result released"
break}
}
}
}
}
def threads = []
noOfThreads.times(){
def thread = Thread.start {
pathFinder()
}
threads << thread
}
println "I start waiting"
threads*.join(MAX_TIME)
println "I joined the finished"
if(finalFound == true) println "Graph is proven to be hamiltonian : " + finalPermutation
else println "Graph was not found hamiltonian"
the following simplified code works fine:
def noOfThreads = 3
def MAX_TIME = 30000
def threads = []
def pathFinder(id){
def t=System.currentTimeMillis()
println "thread $id start"
Thread.sleep(3000+id*100)
println "thread $id end: ${(System.currentTimeMillis() - t)/1000} sec"
}
println "START"
noOfThreads.times{id->
def thread = Thread.start {
pathFinder(id)
}
threads << thread
}
threads*.join(MAX_TIME)
println "END"
result:
START
thread 0 start
thread 1 start
thread 2 start
thread 0 end: 3.002 sec
thread 1 end: 3.1 sec
thread 2 end: 3.2 sec
END
even if you'll have exception in any thread this code reaches the end.
so, multi-threading works fine and the problem somewhere in the rest of your code.
provide runnable code, so we can see the problem ...
I'm new with the concepts of concurrency and threads in Linux and I tried to solve a relative simple problem. I create two threads which run the same function which increment a global variable. What I really want from my program is to increment that variable alternatively, namely ,say in each step the thread that increment that variable prints to the screen a message , so the expected output should look like:
Thread 1 is incrementing variable count... count = 1
Thread 2 is incrementing variable count... count = 2
Thread 1 is incrementing variable count... count = 3
Thread 2 is incrementing variable count... count = 4
and so on.
I tried an implementation with a semaphore which ensures mutual exclusion, but nonetheless the result resembles this:
Thread 2 is incrementing variable count... count = 1
Thread 2 is incrementing variable count... count = 2
Thread 2 is incrementing variable count... count = 3
Thread 2 is incrementing variable count... count = 4
Thread 2 is incrementing variable count... count = 5
Thread 1 is incrementing variable count... count = 6
Thread 1 is incrementing variable count... count = 7
Thread 1 is incrementing variable count... count = 8
Thread 1 is incrementing variable count... count = 9
Thread 1 is incrementing variable count... count = 10
My code looks like:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
int count = 0;
sem_t mutex;
void function1(void *arg)
{
int i = 0;
int *a = (int*) arg;
while (i < 10)
{
sem_wait(&mutex);
count++;
i++;
printf("From the function : %d count is %d\n",*a,count);
sem_post(&mutex);
}
}
int main()
{
pthread_t t1,t2;
int a = 1;
int b = 2;
pthread_create(&t1,NULL,(void *)function1,&a);
pthread_create(&t2,NULL,(void *)function1,&b);
sem_init(&mutex,0,1);
pthread_join(t2,NULL);
pthread_join(t1,NULL);
sem_destroy(&mutex);
return 0;
}
My big question is now , how do I achieve this alternation between threads? I got mutual exclusion , but the alternation is still missing. Maybe I lack a good insight of semaphores usage, but I would be very grateful if someone would explain that to me. (I have read several courses on this topic ,namely,Linux semaphores,concurrency and threads, but the information there wasn't satisfactory enough)
Mutex locks don't guarantee any fairness. This means that if thread 1 releases it and then attempts to get it again, there is no guarantee that it won't - it's just guarantees that no two pieces of code can be running in that block at the same time.
EDIT: Removed previous C-style solution because it was probably incorrect. The question asks for a synchronization solution.
If you really want to do this correctly you would use something called a monitor and a guard (or condition variable). I'm not too familiar with C and pThreads so you would need to take a look how to do it with that, but in Java it would look something like:
public class IncrementableInteger {
public int value;
#Override
public String toString() {
return String.valueOf(value);
}
}
#Test
public void testThreadAlternating() throws InterruptedException {
IncrementableInteger i = new IncrementableInteger();
Monitor m = new Monitor();
Monitor.Guard modIsZeroGuard = new Monitor.Guard(m) {
#Override public boolean isSatisfied() {
return i.value % 2 == 0;
}
};
Monitor.Guard modIsOneGuard = new Monitor.Guard(m) {
#Override public boolean isSatisfied() {
return i.value % 2 == 1;
}
};
Thread one = new Thread(() -> {
while (true) {
m.enterWhenUninterruptibly(modIsZeroGuard);
try {
if (i.value >= 10) return;
i.value++;
System.out.println("Thread 1 inc: " + String.valueOf(i));
} finally {
m.leave();
}
}
});
Thread two = new Thread(() -> {
while (true) {
m.enterWhenUninterruptibly(modIsOneGuard);
try {
if (i.value >= 10) return;
i.value++;
System.out.println("Thread 2 inc: " + String.valueOf(i));
} finally {
m.leave();
}
}
});
one.start();
two.start();
one.join();
two.join();
}
In a loop I create 4 closures and add them to a list:
closureList = []
for (int i=0; i<4; i++) {
def cl = {
def A=i;
}
closureList.add(cl)
}
closureList.each() {print it.call()println "";};
This results in the following output:
4
4
4
4
But I would have expected 0,1,2,3 instead. Why does the 4 closures have the same value for A?
Yeah, this catches people out, the free variable i is getting bound to the last value in the for loop, not the value at the time the closure was created.
You can either, change the loop into a closure based call:
closureList = (0..<4).collect { i ->
{ ->
def a = i
}
}
closureList.each { println it() }
Or create an extra variable that gets re-set every time round the loop, and use that:
closureList = []
for( i in (0..<4) ) {
int j = i
closureList << { ->
def a = j
}
}
closureList.each { println it() }
In both of these variants the variable closed by the closure is created afresh each time round the loop, so you get the result you'd expect