sending signal to a blocked thread with a timer - multithreading

I am running two processes (Process A and B) on the same core. Process B is multithreaded in which one thread is sending Signal to the next thread to wake it and start its work. At a time, only one thread of process B can run on the common core.
**//Process A**
#define _GNU_SOURCE
#include <sched.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
int main(int argc, char const *argv[])
{
struct timeval tval_result;
cpu_set_t my_set;
CPU_ZERO(&my_set);
CPU_SET(2, &my_set);
sched_setaffinity(0, sizeof(cpu_set_t), &my_set);
long int loopNum;
while(1)
{
gettimeofday(&tval_result, NULL);
printf("Dummy Time elapsed: %ld.%06ld\n", (long int)tval_result.tv_sec, (long int)tval_result.tv_usec);
//for(loopNum = 1; loopNum <= 100000; loopNum++);
//printf("Dummy!!! # \n");
}
return 0;
}
Following is the code of Process B.
//Import
#define _GNU_SOURCE
#include <sched.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#define NUM_THREADS 100
//global variables
pthread_cond_t condA[NUM_THREADS+1] = PTHREAD_COND_INITIALIZER;
pthread_cond_t condB = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_t tid[NUM_THREADS];
int state = 0;
void *threadA(void *data_)
{
int i = 0, rValue;
long int loopNum;
int turn = (intptr_t)data_;
struct timeval tval_result;
while(1)
{
cpu_set_t my_set;
CPU_ZERO(&my_set);
CPU_SET(2, &my_set);
sched_setaffinity(0, sizeof(cpu_set_t), &my_set);
/* Wait for state A */
pthread_mutex_lock(&mutex);
// while (state != STATE_A)
if(state != turn)
{
pthread_cond_wait(&condA[turn], &mutex);
}
pthread_mutex_unlock(&mutex);
//do stuff
gettimeofday(&tval_result, NULL);
printf("Time elapsed: %ld.%06ld\n", (long int)tval_result.tv_sec, (long int)tval_result.tv_usec);
//for(loopNum = 1; loopNum <= 10000000000; loopNum++);
//printf("Hello Thread # %d\n", turn);
/* Set state TRUE for next thread */
pthread_mutex_lock(&mutex);
state = (state +1)%NUM_THREADS;
pthread_cond_signal(&condA[state]);
pthread_mutex_unlock(&mutex);
}
}
int main(int argc, char *argv[])
{
int data = 0;
int err;
while(data < NUM_THREADS)
{
//create our threads
err = pthread_create(&tid[data], NULL, threadA, (void *)(intptr_t)data);
if(err != 0)
printf("\ncan't create thread :[%s]", strerror(err));
else
printf("\n Thread created successfully\n");
data++;
}
pthread_exit(NULL);
}
I want to interleave the execution of process B in between threads of Process A for a very short duration (less than 1 microseconds). So, when thread i of process B finishes its work it'll send the signal to the next thread i+1 and in between, I want process A to come. This should be repeated for the rest of the course of execution.
When I am running above programs, process A is not able to come in between threads of the Process B. Is there any mechanism by which I can send signal with some timer so that signal does not reach the next thread immediately (and hence Process A comes for some time between two consecutive threads.)

There's no way you can force the Linux scheduler at that level.
You'll have to "signal" process A and then let it "signal" the other B thread.
But to "signal" may be a user space mechanism like spinning on a variable in shared memory.
I'd suggest you first try it with normal signals (going through the kernel) and see is the latency good enough. Only if it's too long, go play with spinning in user space.
Don't expect all that to work always under 1us. You'll probably get lots of jitter will have to move processes away from that core to reduce it, regardless of spinning or using kernel signalling.
For kernel signalling you may also use sockets, pipes, futexes,...
Now my question is, if you're running all that on one core, as you said, why not run it as a single thread - Just have one thread call B1, then A, then B2?

Related

What happens without a binary semaphore

Assume the code below demonstrating a binary semaphore example.
In this example, we have a pthread that reads the source.txt and attempts to copy the content to destination.txt while locking it using a binary semaphore.
What happens in the comment section below without the semaphore?
#include <cstdlib>
#include <memory>
#include <filesystem>
#define _TIMESPEC_DEFINED
#include <pthread.h>
#include <semaphore.h>
#include <thread>
#include <valarray>
pthread_t StartFileAccessThread();
void *CopyFile(void *parameters);
int main(int argc, char* argv[])
{
pthread_t thread = StartFileAccessThread();
void *returnValue;
pthread_join(thread, &returnValue);
getchar();
return EXIT_SUCCESS;
}
pthread_t StartFileAccessThread()
{
std::string sourcePath("source.txt");
std::string destinationPath("dest.txt");
sem_t semaphore;
sem_init(&semaphore, 0, 0);
pthread_t thread;
void *parameters[3];
parameters[0] = &semaphore;
parameters[1] = &sourcePath;
parameters[2] = &destinationPath;
pthread_create(&thread, nullptr, &CopyFile, parameters);
// What happens without the binary semaphore?
sem_wait(&semaphore);
sem_destroy(&semaphore);
printf("Freeing ressources.\n");
return thread;
}
void *CopyFile(void *rawParameter)
{
void **parameters = static_cast<void **>(rawParameter);
sem_t *semaphore = static_cast<sem_t *>(parameters[0]);
std::string sourcePath(*static_cast<std::string *>(parameters[1]));
std::string destinationPath(*static_cast<std::string *>(parameters[2]));
sem_post(semaphore);
std::this_thread::sleep_for(std::chrono::seconds(2));
copy_file(sourcePath, destinationPath, std::experimental::filesystem::copy_options::overwrite_existing);
printf("File copied \n");
return nullptr;
}
What happens in the comment section below without the semaphore?
Without the semaphore, function startFileAccessThread() may return before the new thread finishes (or starts) copying its parameters from the argument object. That object is local to startFileAccessThread(), so its lifetime ends when that function returns. Undefined behavior results if the copy thread's accesses to it do not happen before that.

Pause thread execution without using condition variable or other various synchronization pritmives

Problem
I wish to be able to pause the execution of a thread from a different thread. Note the thread paused should not have to cooperate. The pausing of the target thread does not have to occur as soon as the pauser thread wants to pause. Delaying the pausing is allowed.
I cannot seem to find any information on this, as all searches yielded me results that use condition variables...
Ideas
use the scheduler and kernel syscalls to stop the thread from being scheduled again
use debugger syscalls to stop the target thread
OS-agnostic is preferable, but not a requirement. This likely will be very OS-dependent, as messing with scheduling and threads is a pretty low-level operation.
On a Unix-like OS, there's pthread_kill() which delivers a signal to a specified thread. You can arrange for that signal to have a handler which waits until told in some manner to resume.
Here's a simple example, where the "pause" just sleeps for a fixed time before resuming. Try on godbolt.
#include <unistd.h>
#include <pthread.h>
#include <signal.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
void safe_print(const char *s) {
int saved_errno = errno;
if (write(1, s, strlen(s)) < 0) {
exit(1);
}
errno = saved_errno;
}
void sleep_msec(int msec) {
struct timespec t = {
.tv_sec = msec / 1000,
.tv_nsec = (msec % 1000) * 1000 * 1000
};
nanosleep(&t, NULL);
}
void *work(void *unused) {
(void) unused;
for (;;) {
safe_print("I am running!\n");
sleep_msec(100);
}
return NULL;
}
void handler(int sig) {
(void) sig;
safe_print("I am stopped.\n");
sleep_msec(500);
}
int main(void) {
pthread_t thr;
pthread_create(&thr, NULL, work, NULL);
sigset_t empty;
sigemptyset(&empty);
struct sigaction sa = {
.sa_handler = handler,
.sa_flags = 0,
};
sigemptyset(&sa.sa_mask);
sigaction(SIGUSR1, &sa, NULL);
for (int i = 0; i < 5; i++) {
sleep_msec(1000);
pthread_kill(thr, SIGUSR1);
}
pthread_cancel(thr);
pthread_join(thr, NULL);
return 0;
}

Why the program didn't execute some sentences in this C programming or unix programming(execvp() System calls)?

I have the following program, when I run the program, I feel really confused that why my program didn't excute
int num=i;
printf("it is No.%d !",num);
printf("hello , I will excute execvp!");
My program basically create 6 child processes to excute executionbode() function, and then use execvp to overload original program. However, everytime when I run the program, the string "hello, I will execute execvp" never shows up! Also I think those three sentences above also didn't execute in the running program? can someone tell me why? Here is my program
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include "makeargv.h"
#include "redirection.h"
#include <sys/wait.h>
int executionnode(int i);
int main(){
pid_t childpid;
int i;
int row=6;
for(i=0;i<row;i++)
{ childpid=fork();
if(childpid==0)
continue;
else if (childpid>0)
executionnode(i);
else {
perror("something wrong");
exit(1);
}
}
}
int executionnode(int i){
sleep(i);
printf("hello, I am process:%ld\n",(long)getpid());
wait(NULL);
char *execArgs[] = { "echo", "Hello, World!", NULL };
int num=i;
printf("it is No.%d !",num);
printf("hello , I will excute execvp!");
execvp("echo", execArgs);
}
Can someone tell me why? and how to fix it? I feel it is really strange? Is it because of execvp() functions? I just began to learn operating system,so I am really confused about it! Thank you for helping me!
As user3629249 said you have some confusion. You'll get many children of children of children... and that wait(NULL) is useless :).
I used this structure to got your goal in my OS subject excercises.
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#define N 5
int main(int argc, char const *argv[])
{
pid_t pid,pids[N];
int i, num_pids = 0;
int state = 0;
int prior[]={1,3,5,2,4};
pid_t parent_pid = getpid();
printf("Parent pid is %i\n",father_pid);
// This for loop is the key
for (i = 0; i < N && getppid() != parent_pid; i++)
{
if ((pid = fork()) < 0)
{
printf ("fork error\n");
exit(-1);
}
pids[num_pids++] = pid;
}
if (pid == 0) // Child processes
{
printf("I am the child %i\n",getpid());
}
else // Parent process
{
for (i = 0; i < N; i++)
{
int pid_index = prior[i]-1; // Array starts with 0
pid = waitpid(pids[pid_index]);
printf("Children %i ended\n",pids[indice_pid]);
printf("%i alive children\n",N-1-i);
}
}
return 0;
}
This structure works because you save the parent's pid in parent_pid variable and compare the parent of each process pid with getppid(). If this pid is different that parent_pid, this proccess is the parent. In another case the process is a child so it has to stop (these processes don't have to fork). With this way you can get only the forks you need.
The rest of the code is the same: Pid==0 is child process and any other is the parent. You can call executionnode(int i) in child processes block (remember, pid==0 !!! you have a mistake). i variable should have the right value in each call I think.
Good luck!

how can I configure the context switch time slice in Linux?

I have following code.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void* a(void* ptr) {
while(1){
printf("1");
printf("2");
printf("3");
printf("4");
}
}
int main(int argc, char** argv) {
pthread_t t;
pthread_create(&t, NULL, a, 0);
while(1){
printf("a");
printf("b");
printf("c");
printf("d");
}
pthread_join(t, NULL);
return 0;
}
the result of this code is "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd1234123412341234..........."
but I want them to be mixed like "ab12c3d4a1bcda23b......"
how can I configure the scheduling time slice of a thread?
is this possible?
thank you in advance
You can modify scheduling behaviour by setting the sched param (pthread_setschedparam(3)) to for example SCHED_RR (RR means Round Robin). There is SCHED_FIFO, SCHED_RR and SCHED_OTHER with SCHED_OTHER being the default.

Keeping number of threads constant with pthread in C

I tried to find a solution in order to keep the number of working threads constant under linux in C using pthreads, but I seem to be unable to fully understand what's wrong with the following code:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define MAX_JOBS 50
#define MAX_THREADS 5
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int jobs = MAX_JOBS;
int worker = 0;
int counter = 0;
void *functionC() {
pthread_mutex_lock(&mutex1);
worker++;
counter++;
printf("Counter value: %d\n",counter);
pthread_mutex_unlock(&mutex1);
// Do something...
sleep(4);
pthread_mutex_lock(&mutex1);
jobs--;
worker--;
printf(" >>> Job done: %d\n",jobs);
pthread_mutex_unlock(&mutex1);
}
int main(int argc, char *argv[]) {
int i=0, j=0;
pthread_t thread[MAX_JOBS];
// Create threads if the number of working threads doesn't exceed MAX_THREADS
while (1) {
if (worker > MAX_THREADS) {
printf(" +++ In queue: %d\n", worker);
sleep(1);
} else {
//printf(" +++ Creating new thread: %d\n", worker);
pthread_create(&thread[i], NULL, &functionC, NULL);
//printf("%d",worker);
i++;
}
if (i == MAX_JOBS) break;
}
// Wait all threads to finish
for (j=0;j<MAX_JOBS;j++) {
pthread_join(thread[j], NULL);
}
return(0);
}
A while (1) loop keeps creating threads if the number of working threads is under a certain threshold. A mutex is supposed to lock the critical sections every time the global counter of the working threads is incremented (thread creation) and decremented (job is done). I thought it could work fine and for the most part it does, but weird things happen...
For instance, if I comment (as it is in this snippet) the printf //printf(" +++ Creating new thread: %d\n", worker); the while (1) seems to generate a random number (18-25 in my experience) threads (functionC prints out "Counter value: from 1 to 18-25"...) at a time instead of respecting the IF condition inside the loop. If I include the printf the loop seems to behave "almost" in the right way... This seems to hint that there's a missing "mutex" condition that I should add to the loop in main() to effectively lock the thread when MAX_THREADS is reached but after changing a LOT of times this code for the past few days I'm a bit lost, now. What am I missing?
Please, let me know what I should change in order to keep the number of threads constant it doesn't seem that I'm too far from the solution... Hopefully... :-)
Thanks in advance!
Your problem is that worker is not incremented until the new thread actually starts and gets to run - in the meantime, the main thread loops around, checks workers, finds that it hasn't changed, and starts another thread. It can repeat this many times, creating far too many threads.
So, you need to increment worker in the main thread, when you've decided to create a new thread.
You have another problem - you should be using condition variables to let the main thread sleep until it should start another thread, not using a busy-wait loop with a sleep(1); in it. The complete fixed code would look like:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#define MAX_JOBS 50
#define MAX_THREADS 5
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER;
int jobs = MAX_JOBS;
int workers = 0;
int counter = 0;
void *functionC() {
pthread_mutex_lock(&mutex1);
counter++;
printf("Counter value: %d\n",counter);
pthread_mutex_unlock(&mutex1);
// Do something...
sleep(4);
pthread_mutex_lock(&mutex1);
jobs--;
printf(" >>> Job done: %d\n",jobs);
/* Worker is about to exit, so decrement count and wakeup main thread */
workers--;
pthread_cond_signal(&cond1);
pthread_mutex_unlock(&mutex1);
return NULL;
}
int main(int argc, char *argv[]) {
int i=0, j=0;
pthread_t thread[MAX_JOBS];
// Create threads if the number of working threads doesn't exceed MAX_THREADS
while (i < MAX_JOBS) {
/* Block on condition variable until there are insufficient workers running */
pthread_mutex_lock(&mutex1);
while (workers >= MAX_THREADS)
pthread_cond_wait(&cond1, &mutex1);
/* Another worker will be running shortly */
workers++;
pthread_mutex_unlock(&mutex1);
pthread_create(&thread[i], NULL, &functionC, NULL);
i++;
}
// Wait all threads to finish
for (j=0;j<MAX_JOBS;j++) {
pthread_join(thread[j], NULL);
}
return(0);
}
Note that even though this works, it isn't ideal - it's best to create the number of threads you want up-front, and have them loop around, waiting for work. This is because creating and destroying threads has significant overhead, and because it often simplifies resource management. A version of your code rewritten to work like this would look like:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#define MAX_JOBS 50
#define MAX_THREADS 5
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
int jobs = MAX_JOBS;
int counter = 0;
void *functionC()
{
int running_job;
pthread_mutex_lock(&mutex1);
counter++;
printf("Counter value: %d\n",counter);
while (jobs > 0) {
running_job = jobs--;
pthread_mutex_unlock(&mutex1);
printf(" >>> Job starting: %d\n", running_job);
// Do something...
sleep(4);
printf(" >>> Job done: %d\n", running_job);
pthread_mutex_lock(&mutex1);
}
pthread_mutex_unlock(&mutex1);
return NULL;
}
int main(int argc, char *argv[]) {
int i;
pthread_t thread[MAX_THREADS];
for (i = 0; i < MAX_THREADS; i++)
pthread_create(&thread[i], NULL, &functionC, NULL);
// Wait all threads to finish
for (i = 0; i < MAX_THREADS; i++)
pthread_join(thread[i], NULL);
return 0;
}

Resources