How to make multiple threads execute sequentially? - c

I want to have multiple threads execute sequentially.
Because I need to do some work on CPU cache. So I need two threads to run on different CPU cores. Two physical CPU cores share the Last level cache. My job is to operate Last level cache
This can be achieved with pthread_attr_setaffinity_np.
This can be achieved by locking.
But when implementing it, I found it easy to have two threads execute sequentially.
void trasmitter_func(void *addr){
while(1){
pthread_mutex_lock(&lock1);
if (sequence == 0) {
pthread_cond_wait(&cond1, &lock1);
}
if(sequence == -1){
pthread_cond_signal(&cond1);
pthread_mutex_unlock(&lock1);
break;
}
printf("trasmitter start\n");
sequence = 0;
pthread_cond_signal(&cond1);
pthread_mutex_unlock(&lock1);
}
}
void receiver_func(void *addr) {
for(int i=0;i<SAMPLE_NUMBER;i++){
pthread_mutex_lock(&lock1);
if (sequence == 1) {
pthread_cond_wait(&cond1, &lock1);
}
// printf("receiver start\n");
sequence = 1;
pthread_cond_signal(&cond1);
pthread_mutex_unlock(&lock1);
}
sequence = -1;
}
But when implementing three threads, I need to use two locks and two pthread_cond_signal. And the controls are complicated. I'm curious, is there some simple implementation here that would allow three or more than three threads to execute sequentially?
I can simply pass some tags and functions to ensure their execution.
execute_func_sequence(0, func_1);
execute_func_sequence(1, func_2);
execute_func_sequence(2, func_3);
execute_func_sequence(3, func_4);
Then fun_1 to fun_4 will be executed sequentially.
This seems to be difficult to implement using locks and signals.
What I want to emphasize is: each is not executed once.
receiver start
trasmitter start
receiver start
trasmitter start
receiver start
trasmitter start
receiver start
trasmitter start
receiver start
trasmitter start
receiver start
trasmitter start
receiver start
trasmitter start
receiver start
trasmitter start
receiver start
trasmitter start
The execution result of the above sample code is as follows. I need to execute two threads non-stop sequentially.
I want to run multiple threads in this form.
func_1(){
for(int i=0;i <SAMPLE_NUMBER; i++){
do work1;
// block and enter func_2;
}
end = true;
}
func_1(){
while(1){
do work2;
if(end)
break
// block and enter func_3;
}
}
func_1(){
while(1){
do work3;
if(end)
break
// block and enter func_1;
}
}
Finally got this working.
work1,
work2,
work3,
work1,
work2,
work3,
work1,
work2,
work3,
...
work1,
work2,
work3,

A possible way of implementing what you want is:
void func_1() {
// do work...
sem_post(&thread2_sem);
}
void func_2() {
sem_wait(&thread2_sem);
// do work...
sem_post(&thread3_sem);
}
void func_3() {
sem_wait(&thread3_sem);
// do work...
sem_post(&thread4_sem);
}
void func_4() {
sem_wait(&thread4_sem);
// do work...
}
int main() {
sem_init(&thread2_sem, 0, 0);
sem_init(&thread3_sem, 0, 0);
sem_init(&thread4_se,, 0, 0);
NEW_THRAD(func_1)
NEW_THRAD(func_2)
NEW_THRAD(func_3)
NEW_THRAD(func_4)
}
As you can see, every thread is locked in some semaphore, and the previous thread is responsible for unlocking it.
The program starts with all the semaphores initialized to zero and, on each step, one semaphore gets incremented in order to activate the next thread, which will immediately decrement it.
All semaphores must go back to zero in case there's "another batch". i.e.: the threads are ready to process another order (whatever that means).
Note the example functions don't have a loop, y assume you would want something like:
void func_3() {
while (g_running) {
sem_wait(&thread3_sem);
// do work...
sem_post(&thread4_sem);
}
}
In this case, you may need something similar to wake up func_1.

Related

to interrupt a sleeping thread when main thread is to exit

I have a main thread which create child threads to do various task. There is a child thread which is tasked to report on the status every 100s
My current mechanism of stopping the thread is to observe a global boolean. Somewhat like this
Child thread
void* ReportThread(bool* operation)
{
while(*operation)
{
// do its reporting task
// ........
int counter = 0;
while( counter < 100 && operation )
{
// let it sleep for 1 seconds and wake up to check
sleep(1);
sleepCounter += 1;
}
}
}
Parent (Main) Thread:
bool operation = false;
int main(){
pthread_t tid;
err = pthread_create(&tid), NULL, &ReportThread, &operation);
printf("Please input esc to end operation \n");
while ((ch = getchar()) != 27);
operation =true;
pthread_join(tid,NULL);
return 0;
}
The problem:
It seem that using sleep(n). The number of seconds seem very inconsistent. When the program is stopped, this thread takes a while maybe 10 second to actually stop
Is there a way to interrupt a thread to sleep? I heard you could use signal. I am coding in linux
Can I just simply just use a pthread_cancel(tid) instead of pthread_join(tid)?
Regards
This part
while( counter < 100 || operation )
{
// let it sleep for 1 seconds and wake up to check
sleep(1);
sleepCounter += 1;
}
is wrong.
First I assume that sleepCounter += 1; is really a typo and that it should be:
while( counter < 100 || operation )
{
// let it sleep for 1 seconds and wake up to check
sleep(1);
counter += 1;
}
Then the problem is that even if operation is set to false by some other thread, the while will not finish until counter reach 100.
The code should be
while( counter < 100 && operation )
{
// let it sleep for 1 seconds and wake up to check
sleep(1);
counter += 1;
}
Further, in main you never set operation to false. Another typo?
You don't need two while loops. And if you want to set a timer, use time functions for it, because sleep is a cancellation point and it is not guaranteed that sleep actually sleeps that amount of time.
Example:
void* ReportThread(void *args)
{
time_t start = time(NULL);
time_t now;
bool *operation = (bool*) args;
while (*operation) { //while active
now = time(NULL); //get current time
if (now - start >= 100) { //if the threshold is exceeded
start = now; //reset timer
//and probably do other stuff
}
sleep(1); //sleep for one second
}
return NULL;
}
The example above has a max lag of one second, that means if you set operation to false right at that moment when the thread entered the sleep state, you have to wait until sleep returns, only then it will recognize the modified state. The example also has the advantage, that you can easily modify the threshold value (since it depends on the 'real' time, instead of a counter and a non accurate sleep time).
Btw. the variable operation should be either an atomic boolean or protected by a mutex (since it is accessed from different threads).
To answer the questions of your problem:
should be answered by the example above
since i mentioned it before, sleep is a cancellation point, that means it gets interrupted if the process handles a signal (see man pthreads - section Cancellation points).
see man pthread_cancel - section Notes
On Linux, cancellation is implemented using signals. Under the NPTL threading implementation, the first real-time signal (i.e., signal 32) is used for this purpose. On LinuxThreads, the second real-time signal is used, if real-time signals are available, otherwise SIGUSR2 is used.
You cannot use pthread_cancel over pthread_join! You have to use pthread_join in either case (described in detail in the man page).
I don't know if this will fix all your problems, but it's a bit too much for a comment. One problem, your ReportThread function signature is wrong. It should be:
void* ReportThread(void* args);
And then in that function you need to do something like:
void* ReportThread(void* args)
{
bool* operation = (bool*)args;
while(*operation)
{
...
}
}
I'm not sure how it's working right now, but your compiler should at least be issuing a warning trying to convert a bool* type to a bool.
Also be aware of race conditions on operation

Measuring time parallely to looped sigwait in C

I have a main proccess which sends signal to the children, like this:
void handleInputs(query_data *q_data)
{
char input[DEFAULT_INPUT_SIZE];
while(1)
{
if(fgets(input,DEFAULT_INPUT_SIZE,stdin)==NULL) ERR("FGETS");
input[strlen(input)-1] = '\0';
if(!strcmp(input,"exit"))
{
kill(0,SIGTERM);
exit(EXIT_SUCCESS);
}
else if(!strcmp(input,"index"))
kill(0,SIGUSR2);
else if(!strcmp(input,"status"))
kill(0,SIGUSR1);
else
{
char* token = strtok(input, " ");
if(!token) printf("Wrong input\n");
else
{
if(!strcmp(token,"query"))
{
initializeQueryNumbers(q_data,token);
createQueryThread(q_data);
}
else printf("Wrong input\n");
}
}
}
}
Then I have a child processes which wait for signals using sigwait in a loop like this:
void waitForSignals(data* ch_data)
{
char* pid_directory = strConcat(ch_data->dir, "/.numf_pid");
int signo;
for(;;)
{
//how to make this block independent to the sigwait
printf("time elapse: %ld interval: %d\n",time(NULL)-ch_data->end, ch_data->i);
if((time(NULL)- ch_data->end)>ch_data->i && ch_data->status ==0)
{
printf("Time elapsed from the last indexing > %d\n",ch_data->i);
createIndexingThread(ch_data);
}
//end here
if(sigwait(&(ch_data->mask), &signo)) ERR("SIGWAIT");
switch(signo)
{
case SIGUSR1:
if(ch_data->status == 1)
{
printf("Indexing in progress for directory: %s\n",ch_data->dir);
printf("Time elapsed: %ld\n", time(NULL)- ch_data->start);
}
else printf("No indexing in progress for directory: %s\n",ch_data->dir);
break;
case SIGUSR2:
if(ch_data->status ==0)
createIndexingThread(ch_data);
else printf("Indexing already in progess for directory: %s\n",ch_data->dir);
break;
case SIGTERM:
if(remove(pid_directory)<0) ERR("REMOVE");
free(pid_directory);
if(pthread_cancel(ch_data->tid)==0)
printf("Stopped the indexing of directory %s\n",ch_data->dir);
exit(EXIT_SUCCESS);
}
}
if(pthread_join(ch_data->tid,NULL)) ERR("PTHREAD_JOIN");
}
My child proccess creates thread which does some indexing. I want to create such thread when signaled SIGUSR2 from main proccess (which is working fine) or when time elapsed from last indexing is bigger than some user-given time (stored in ch_data->i). However right now the block between the comments only comes alive after I send some signal from the main proccess. What is the best way to make it work in parallel?
If I understand correctly, you are asking how to schedule a threaded operation performed either upon a signal or upon time elapsed since the most recent operation, whichever comes first.
You might use sigtimedwait(interesting_sigs, NULL, timeout) instead of sigwait, recomputing your timeout as needed.
You might arm a POSIX timer to launch the operation (or, perhaps, to signal yourself). You'll need to check that the operation hasn't been performed too recently, and you'll need to re-arm (reschedule) the next timer appropriately, perhaps at the end of every operation.
You might simply have an idle-looping background thread that does what a timer would do. Sometimes these are easier to reason about than sigevent timers.
You might incorporate an event-driven framework like libevent that knows how to handle timeouts and signals and not worry about the implementation. You'll likely still need to recompute the expiry, however.

Unique semaphore for each thread

I have been assigned a modified version of the "Santa Claus" semaphore problem.
Santa Claus is a thread that randomly wakes up to check how many and what kind of threads are waiting to report to him (Work elves and Collecting elves)
What I have made are work elf and collecting elf threads:
void *collectingElf(void *arg, int semaphoreIndex) {
while (1) {
sem_wait(&elveCountMutex); //semaphore for critical section, the number of elves
printf("\nCollecting! %d\n", (int) pthread_self()); // thread is collecting stuff
sleep((unsigned int) (rand() % 4)); // thread sleeps for a random amount of time
printf("Done collecting! %d\n", (int) pthread_self()); // Print process ID, just for easier tracking
sem_post(&elveCountMutex); // Release the elve count semaphore
sem_wait(&collectingElveSem);
}
}
void *workingElf(void *arg) //same as collecting elf
{
while (1) {
sem_wait(&elveCountMutex);
printf("\nWorking! %d\n", pthread_self());
sleep(1);
workingElveCount++;
printf("Done working! %d\n", pthread_self());
sem_wait(&workElfSem);
sem_post(&elveCountMutex);
}
}
So here the elve counts are protected, since the threads can only access the counters when elveCountMutex is locked. This I can understand and this seems logical. Afterwards the thread should block and wait for Santa to unblock it.
So, from what I read, once semaphore reaches value 0, thread will block. Anything above 0 will not block it, and negative value indicates how many threads are waiting for the semaphore to be unlocked.
So, once the threads running are finished, they decrement the semaphore, and block.
However, what I cannot seem to grasp is this part of the assignment:
For a collecting meeting to start, at least one work elf and three collecting elves are necessary. • If enough elves are present that both meetings could start, the collecting-meeting
always has priority, and all work-elves not needed anymore resume their work.
Say if I have 3 work elves, and I need only 1, how do I release the remaining 2 threads? Do I need a separate semaphore for each thread? Or am I missing something?
Edit: My bad, I completely forgot to tell about the Santa implementation.
Santa wakes up and releases the semaphores, in this way:
void* Santa(void *arg)
{
while (1) {
sleep((unsigned)rand() % 4); //Santa sleeps randomly between 0 and 3 seconds;
sem_wait(&elveCountMutex); //access both elf counters
if(workingElveCount>=2 && collectingElveCount >= 3) //decide which meeting should commence
{
int releaseWorkElveCount = workingElveCount-1;
for(int i = 0;i<releaseWorkElveCount;i++)
{
sem_post(&workElfSem);
}
sleep(5);
collectingMeeting(&collectingMeetingThread); //This just prints that we are in a collecting meeting
pthread_join(collectingMeetingThread,0);
sem_wait(&elveCountMutex);
for(int i=0;i<workingElveCount;i++)
{
sem_post(&workElfSem);
}
for(int i=0;i<collectingElveCount;i++)
{
sem_post(&collectingElveSem);
}
workingElveCount=0;
collectingElveCount=0;
}
}
I do not understand your management of semaphore
In
void *collectingElf(void *arg, int semaphoreIndex) {
while (1) {
...
sem_wait(&collectingElveSem);
}
}
that gets but never releases collectingElveSem, and that in an infinite loop ?
In
void *workingElf(void *arg) //same as collecting elf
{
while (1) {
sem_wait(&elveCountMutex);
...
sem_wait(&workElfSem);
}
}
that get but never release elveCountMutex and workElfSem, and that in an infinite loop. collectingElf also (try to) get elveCountMutex but I will not able to do after one turn in workingElf
If your semaphore are not recursive workingElf will also be blocked after one turn because not able to get again the semaphores. If the semaphore are recursive this cannot be for an infinite deep and workingElf will block itself after enough loops

While loop synchronization

I am working on a project with a user defined number of threads I am using 7 at the moment. I have a while loop that runs in each thread but I need all of the threads to wait for each other at the end of the while loop. The tricky thing is that some of the threads do not all end on the same number of times through the loop.
void *entryFunc(void *param)
{
int *i = (int *)param;
int nextPrime;
int p = latestPrime;
while(latestPrime < testLim)
{
sem_wait(&sem);
nextPrime = findNextPrime(latestPrime);
if(nextPrime != -1)
{
latestPrime = nextPrime;
p = latestPrime;
}
else
{
sem_post(&sem);
break;
}
sem_post(&sem);
if(p < 46341)
{
incrementNotPrimes(p);
}
/*
sem_wait(&sem2);
doneCount++;
sem_post(&sem2);
while(go != 1);
sem_wait(&sem2);
doneCount--;
//sem_post(&sem3);
sem_post(&sem2);
*/
}
return NULL;
}
where the chunk of code is commented out is part of my last attempt at solving this problem. That is where the functions all need to wait for each other. I have a feeling I am missing something simple.
If your problem is that on each thread, the while loop has a different numbers of iterations and some threads never reach the synchronization point after exiting the loop, you could use a barrier. Check here for an example.
However you need to decrease the number of threads at the barrier after you exit each thread. Waiting at the barrier will end after count number of threads reached that point.
So you need to update the barrier object each time a thread finishes. And make sure you do this atomically.
As I mentioned in the comments, you should use a barrier instead of a semaphore for this kind of situation, as it should be simpler to implement (barriers have been designed exactly to solve that problem). However, you may still use a semaphore with a little bit of arithmetic
arithmetic: your goal is to have all thread execute the same code path, but somehow the last thread to finish its task should wake all the other threads up. One way to achieve that is to have at the end of the function an atomic counter which each thread would decrement, and if the counter reaches 0, the thread simply calls as many time sem_post as necessary to release all the waiting threads, instead of issuing a sem_wait as the others.
A second method, this time using only a semaphore, is also possible. Since we cannot differentiate the last thread for the others, all the threads must do the same operations with the semaphore, ie try to release everyone, but also wait for the last one. So the idea is to initialize the semaphore to (1-n)*(n+1), so that each of the n-1 first threads would fail at waking up their friends with n+1 calls to sem_post, but still work toward getting the semaphore at exactly 0. Then the last thread would do the same, pushing the semaphore value to n+1, thus releasing the locked threads, and leaving room for it to also perform its sem_wait and be released immediately.
void *entryFunc(void *param)
{
int *i = (int *)param;
int nextPrime;
int p = latestPrime, j;
while(latestPrime < testLim){
nextPrime = findNextPrime(latestPrime);
if(nextPrime != -1)
{
latestPrime = nextPrime;
p = latestPrime;
}
if(p < 46341)
{
incrementNotPrimes(p);
}
}
for (j=0;j<=THREAD_COUNT;j++)
sem_post(&sem);
sem_wait(&sem);
return NULL;
}
The problem with this approach is that it doesn't deal with how the semaphore should be reset in between uses (if your program needs to repeat this mechanism, it will need to reset the semaphore value, since it will end up being 1 after this code has been executed successfully).

Multithreaded messages synchronization

I need to print 2 messages each one in each thread in C and synchronize them.
The one thread prints One and the second prints Two.
So my code is something like that
void printOne(void* empty){
while(1) printf("One ");
}
void printTwo(void* empty){
while(1) printf("Two\n");
}
int main(){
pthread_t t_1,t_2;
pthread_create(&t_1, NULL,(void *)&printOne,NULL);
pthread_create(&t_2, NULL,(void *)&printTwo,NULL);
pthread_join(t_1,NULL);
pthread_join(t_2,NULL);
exit(0);
}
The problem is that randomly prints One and Two but not always in that sequence. I would like to make it print always Two after One. I got a bit confused with the join command.
Thanks in advance!
You are confusing some basic concepts about synchronization here. The pthread_join() function will not guarantee synchronization in the way you are thinking. The join is used to synchronize threads after their execution have finished, i.e., after return is called from within your thread. This way, the calling thread will wait for the specified thread to finish its execution, which is exactly what your code is doing. The main thread is waiting for:
First, t_1 to end
Then, t_2 to end
If t_2 ends before t_1, the main thread will still be blocked by t_1, because this order has to be respected. Of course none of them will finish their execution in your code, since both are stuck in an infinite loop (while(1)).
What you are trying to achieve can be done using many techniques. I'd suggest you to use semaphores (if you want to use the POSIX API) or mutex (already implemented in pthread library).
Here's an example of how your code can be changed to get some synchronization:
void printOne(void* empty){
while(1)
{
sem_wait(&s1); //wait for semaphore s1
printf("One ");
sem_post(&s2); //signal semaphore s2
}
}
void printTwo(void* empty){
while(1)
{
sem_wait(&s2); //wait for semaphore s2
printf("Two\n");
sem_post(&s1); //signal semaphore s1
}
}
sem_t s1, s2; //Declare the semaphores globally, so the threads can access them
int main(){
pthread_t t_1,t_2;
sem_init(&s1, 0, 1); //Initialize s1 with 1
sem_init(&s2, 0, 0); //Initialize s2 with 0
pthread_create(&t_1, NULL,(void *)&printOne,NULL);
pthread_create(&t_2, NULL,(void *)&printTwo,NULL);
pthread_join(t_1,NULL);
pthread_join(t_2,NULL);
exit(0);
}
This way, your code guarantees that one message after another are going to be printed to your output:
One
Two
One
Two
...
Why use threads at all if you want it to be synchronous? Just print them sequentially in main().
Otherwise... I guess you could just run one thread after the other. pthread_join makes the program wait for the thread to finish before continuing.
int main(){
pthread_t t_1,t_2;
pthread_create(&t_1, NULL,(void *)&printOne,NULL);
pthread_join(t_1,NULL);
pthread_create(&t_2, NULL,(void *)&printTwo,NULL);
pthread_join(t_2,NULL);
exit(0);
}
You will have to make a breaking condition in your printOne and printTwo functions if you want the threads to actually finish, though...

Resources