i have little trouble with pthread priority.I have set scheduler FIFO. I have 2 thread, each have diffretnt priority. On my project when i push A or B, one thread start working. Thats fine, but when one thread working and push again B(priority15) and then A(priority 20) my assumption is that thread A jumps before B in stack queue and after first thread will by next thread A with priority 20 and then thread B (15). Is that problem FIFO or something else?
PS: I dont want use semaphore, i want to solve it just with priority and scheduler. Thanks
#include <stdio.h>
#include<pthread.h>
#include<semaphore.h>
#include<unistd.h>
#include <time.h>
#include <sched.h>
sem_t mutex;
void* levelOnefunction(void *a)
{
sem_wait(&mutex);
int* b = (int *) a;
printf("Thread! next main!\n");
printf("sched prior:%d\n",*b);
sleep(3);
sem_post(&mutex);
return 0;
}
int main()
{
char s;
pthread_t t;
pthread_attr_t tattr;
struct sched_param param;
sem_init(&mutex,0,1);
pthread_attr_init(&tattr);
if(pthread_attr_setschedpolicy(&tattr,SCHED_FIFO)!=0)
printf("ERROR FIFO!\n");
//pthread_setschedparam(t,SCHED_FIFO,¶m);
if(pthread_attr_getschedparam(&tattr,¶m)!=0)
printf("ERROR attr get sheduler!\n");
/* int k =pthread_attr_setinheritsched(&tattr,PTHREAD_EXPLICIT_SCHED);
if (k!=0)
printf("ERROR\n"); */
printf("Initial priority is %d \n",param.sched_priority);
int min = sched_get_priority_min(SCHED_FIFO);
int max = sched_get_priority_max(SCHED_FIFO);
printf("MIN - %d ---> MAX - %d\n",min,max);
scanf("%c",&s);
while (s != '\0')
{
if(s=='a')
{
printf("a\n");
param.sched_priority=20;
if(pthread_attr_setschedparam(&tattr,¶m)!=0)
printf("ERROR attr_setschedul!\n");
printf("update priority is:%d\n",param.sched_priority);
if(pthread_create(&t,&tattr,levelOnefunction,(void *)¶m.sched_priority)!=0)
printf("ERROR thread1\n");
pthread_join(t,NULL);
printf("main finish!\n");
printf("%c end\n\n",s);
}
else if(s=='b')
{
printf("b\n");
param.sched_priority=15;
if(pthread_attr_setschedparam(&tattr,¶m)!=0)
printf("ERROR attr_setschedul!\n");
if(pthread_create(&t,&tattr,levelOnefunction,(void *)¶m.sched_priority)!=0)
printf("ERROR Thread 2 ");
pthread_join(t,NULL);
printf("main finish!\n");
printf("%c end\n\n",s);
}
else if(s=='\n')
{
}
else if (s!='a' && s!='b')
{
printf("bad key\n");
}
scanf("%c",&s);
}
sem_destroy(&mutex);
return 0;
}
You are calling pthread_join() in the main thread immediately after creating each child thread.
This means that you never have more than one child thread created at a time - after creating one child thread, the main thread will then block in pthread_join() until that child thread is complete. Only then does it call scanf() again and potentially create another child thread.
Thread priorities don't come into it.
Related
I'm currently writing a program that takes an array that has randomly generated numbers, and uses multithreading to essentially divide the array in equal parts, then each thread will find the minimum of their respective division of the array. Essentially, I need my parent thread to be blocked (have non-busy waiting for parallel processing efficiency) using semaphores while the child threads are looking for the minimum, however the combination of sem_wait and sem_post is not blocking the parent thread as expected.
I've attempted to change the sem_init parameters to different values, however it seems no matter what I do the parent doesn't actually get blocked.
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/timeb.h>
#include <semaphore.h>
#include <stdbool.h>
#include <unistd.h>
#define MAX_SIZE 100000000
#define MAX_THREADS 16
#define RANDOM_SEED 8631
#define MAX_RANDOM_NUMBER 5000
// Global variables
long gRefTime; //For timing
int gData[MAX_SIZE]; //The array that will hold the data
int gThreadCount; //Number of threads
int gDoneThreadCount; //Number of threads that are done at a certain point. Whenever a thread is done, it increments this. Used with the semaphore-based solution
int gThreadMin[MAX_THREADS]; //The minimum value found by each thread
bool gThreadDone[MAX_THREADS]; //Is this thread done? Used when the parent is continually checking on child threads
int indices[MAX_THREADS][3];
// Semaphores
sem_t completed; //To notify parent that all threads have completed or one of them found a zero
sem_t mutex; //Binary semaphore to protect the shared variable gDoneThreadCount
int main(int argc, char *argv[]){
pthread_t tid[MAX_THREADS];
pthread_attr_t attr[MAX_THREADS];
int i, indexForZero, arraySize, min;
// Code for parsing and checking command-line arguments
if(argc != 4){
fprintf(stderr, "Invalid number of arguments!\n");
exit(-1);
}
if((arraySize = atoi(argv[1])) <= 0 || arraySize > MAX_SIZE){
fprintf(stderr, "Invalid Array Size\n");
exit(-1);
}
gThreadCount = atoi(argv[2]);
if(gThreadCount > MAX_THREADS || gThreadCount <=0){
fprintf(stderr, "Invalid Thread Count\n");
exit(-1);
}
indexForZero = atoi(argv[3]);
if(indexForZero < -1 || indexForZero >= arraySize){
fprintf(stderr, "Invalid index for zero!\n");
exit(-1);
}
GenerateInput(arraySize, indexForZero);
CalculateIndices(arraySize, gThreadCount, indices);
InitSharedVars();
SetTime();
// Initialize threads, create threads, and then make the parent wait on the "completed" semaphore
// The thread start function is ThFindMinWithSemaphore
sem_init(&mutex, 0, 1);
sem_init(&completed, 0, 0);
for(i=0; i < gThreadCount; i++){
pthread_attr_init(&attr[i]);
pthread_create(&tid[i],&attr[i],ThFindMinWithSemaphore,&indices[i]);
}
sem_wait(&completed);
if(gThreadDone[i] == true && gThreadMin[i] == min){
for(i=0; i < gThreadCount; i++){
pthread_cancel(tid[i]);
}
}
min = SearchThreadMin();
printf("Threaded FindMin with parent waiting on a semaphore completed in %ld ms. Min = %d\n", GetTime(), min);
void* ThFindMinWithSemaphore(void *param) {
int threadNum = ((int*)param)[0];
int i;
int startIndex = indices[threadNum][1];
int endIndex = indices[threadNum][2];
sem_wait(&completed);
for (i = startIndex; i < endIndex; i++) {
if (gData[i] < gThreadMin[threadNum]){
gThreadMin[threadNum] = gData[i];
}
else if (gData[i] == 0){
sem_post(&completed);
pthread_exit(0);
}
}
sem_wait(&mutex);
gDoneThreadCount++;
sem_post(&mutex);
if (gDoneThreadCount == gThreadCount){
sem_post(&completed);
}
pthread_exit(0);
}
Note that this is not all of the file code that is actually in the file.
I want the main function to wait at the line where it says sem_wait(&completed). The goal is to have the child threads signal the parent by using sem_post when each thread is done searching for their minimum value, or one of the threads has found a zero within the array. Then at that point the main function should continue after receiving that sem_post signal.
As I understand, if the semaphore completed has a count of zero which I have initialized it to that using sem_init(&completed, 0, 0), the caller for sem_wait waits until it receives sem_post from one of the child threads. It appears that my program does not do the wait as expected.
I am writing various code snippets and see what happens. The code below was intended to delay all threads until all reached a certain point in the code and then make each print a distinctive number. Since the threads all do that, the numbers should occur in a random order.
My current problem is that I keep they threads busy waiting. If the number of threads gets big, the program slows down significantly.
I would like to change that by using signals, I found pthread_cond_wait() for that, however I don't see how one would use that to signal all threads that they would please wake up.
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#define threads 10
int counter=0;
pthread_mutex_t lock;
void handler(void *v) {
pthread_mutex_lock(&lock);
counter++;
printf("%d\n", counter);
pthread_mutex_unlock(&lock);
while(counter != threads); // busy waiting
printf("I am first! %d\n", v);
}
int main() {
pthread_t t[threads];
for(int i =0; i < threads; i++) {
pthread_create(&t[i], NULL, handler, (void*) i);
}
for(int i =0; i < threads; i++) {
pthread_join(t[i], NULL);
}
return 0;
}
EDIT: I changed the code to the following, however, it still does not work :/
pthread_mutex_t lock;
pthread_cond_t cv;
void handler(void *v) {
pthread_mutex_lock(&lock);
pthread_cond_wait(&cv, &lock);
printf("I am first! %d\n", v);
pthread_mutex_unlock(&lock);
}
int main() {
pthread_t t[threads];
for(int i =0; i < threads; i++)
pthread_create(&t[i], NULL, handler, (void*) i);
sleep(2);
pthread_cond_signal(&cv);
for(int i =0; i < threads; i++)
pthread_join(t[i], NULL);
return 0;
}
use broadcast()?
http://pubs.opengroup.org/onlinepubs/009696699/functions/pthread_cond_broadcast.html
The pthread_cond_broadcast() function shall unblock all threads currently blocked on the specified condition variable cond.
The pthread_cond_signal() function shall unblock at least one of the threads that are blocked on the specified condition variable cond (if any threads are blocked on cond).
An alternative solution to pthread_cond_broadcast() might be the following.
You define a read-write mutex and lock it in write in the main thread before creating the other threads. The other threads will try to acquire a read-lock but since the main thread have a write-lock they will be blocked.
After the creation of all thread the main-thread releases the lock. All the other threads will be waken up and since many read-locks can coexist the will execute simultaneously (i.e. no one will be locked).
Code might be something like:
pthread_rwlock_t lock;
void handler(void *v) {
if ((res = pthread_rwlock_rdlock(&lock)!=0)
{
exit(1);
}
printf("I am first! %d\n", v);
pthread_rwlock_unlock(&lock);
}
int main() {
pthread_t t[threads];
//First acquire the write lock:
if ((res = pthread_rwlock_wrlock(&lock)!=0)
{
exit(1);
}
for(int i =0; i < threads; i++)
{
pthread_create(&t[i], NULL, handler, (void*) i);
//it is not clear if you want sleep inside the loop or not
// You indented it as if to be inside but not put brackets
sleep(2);
}
pthread_rwlock_unlock(&lock);
for(int i =0; i < threads; i++)
pthread_join(t[i], NULL);
pthread_rwlock_destroy(&lock);
return 0;
}
Try posting the matching remove_from_buffer code.
Better yet, Short, Self Contained, Correct Example
Make a short main() with two threads.
One thread adds to the buffer at random intervals.
The other thread removes from the buffer at random intervals.
Example
CELEBP22
/* CELEBP22 */
#define _OPEN_THREADS
#include <pthread.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>
pthread_cond_t cond;
pthread_mutex_t mutex;
int footprint = 0;
void *thread(void *arg) {
time_t T;
if (pthread_mutex_lock(&mutex) != 0) {
perror("pthread_mutex_lock() error");
exit(6);
}
time(&T);
printf("starting wait at %s", ctime(&T));
footprint++;
if (pthread_cond_wait(&cond, &mutex) != 0) {
perror("pthread_cond_timedwait() error");
exit(7);
}
time(&T);
printf("wait over at %s", ctime(&T));
}
main() {
pthread_t thid;
time_t T;
struct timespec t;
if (pthread_mutex_init(&mutex, NULL) != 0) {
perror("pthread_mutex_init() error");
exit(1);
}
if (pthread_cond_init(&cond, NULL) != 0) {
perror("pthread_cond_init() error");
exit(2);
}
if (pthread_create(&thid, NULL, thread, NULL) != 0) {
perror("pthread_create() error");
exit(3);
}
while (footprint == 0)
sleep(1);
puts("IPT is about ready to release the thread");
sleep(2);
if (pthread_cond_signal(&cond) != 0) {
perror("pthread_cond_signal() error");
exit(4);
}
if (pthread_join(thid, NULL) != 0) {
perror("pthread_join() error");
exit(5);
}
}
OUTPUT
starting wait at Fri Jun 16 10:54:06 2006 IPT is about ready to
release the thread wait over at Fri Jun 16 10:54:09 2006
Hi below is my coding snippet
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#define TIMEOUT 3
int threadFinished = 0;
pthread_mutex_t g_mutex;
void *threadFunction(void* attr)
{
pthread_mutex_lock(&g_mutex);
char *pData = (char*)attr;
if(pData)
{
printf("data from main thread is : %s\n",pData);
}
sleep(10);
threadFinished = 1;
pthread_mutex_unlock(&g_mutex);
return (void*)"This is thread message !";
}
int main()
{
pthread_t tid;
char *retVal = NULL;
int iTimeOut = TIMEOUT;
int i =0;
pthread_mutex_init(&g_mutex,NULL);
pthread_create(&tid,NULL,threadFunction,"Message from main thread");
//printf("itimeout %d , threadrunning %d\n",iTimeOut,threadRunning);
while(iTimeOut!=0 && !threadFinished)
{
printf("waiting %d\n",++i);
sleep(1);
iTimeOut--;
printf("changing the threadfinish varible\n");
//pthread_mutex_lock(&g_mutex); //statement 1
threadFinished = 1;
//pthread_mutex_unlock(&g_mutex); // statement 2
printf("changed the threadfinish varible\n");
}
if(iTimeOut==0)
{
if(!threadFinished)
{
printf("Timed out so cancelling the thread \n");
pthread_cancel(tid);
}
else
{
printf("thread finished \n");
}
}
else
{
printf("thread finished its job \n");
pthread_join(tid,(void*)&retVal);
}
pthread_mutex_destroy(&g_mutex);
threadFinished = 0;
printf("message from thread is : %s\n",retVal);
return 0;
}
When statement1 & statement2 are commented I am expecting child thread to change my testrunning variable first before main thread but it is working properly only when statement1 and statement2 are uncommented.
My question is why in child thread mutex lock is not locking my testrunning variable . it is allowing main thread to modify testrunning variable.
When accessing a variable concurrently from multiple threads, each thread needs to protect access to it via the same mutex. The main() thread fails to do so.
To correct this you could change main()'s while-loop like this:
while (iTimeOut != 0)
{
{
pthread_mutex_lock(&g_mutex);
int finished = threadFinished;
pthread_mutex_unlock(&g_mutex);
if (finished)
{
break;
}
}
printf("waiting %d\n",++i);
sleep(1);
iTimeOut--;
printf("changing the threadfinish varible\n");
pthread_mutex_lock(&g_mutex); //statement 1
threadFinished = 1;
pthread_mutex_unlock(&g_mutex); // statement 2
printf("changed the threadfinish varible\n");
}
Also you might like to consider narrowing locking to where it is necessary inside the thread-function like this:
void *threadFunction(void* attr)
{
char *pData = attr; /* No need to cast here in C, as opposed to C++. */
if(pData)
{
printf("data from main thread is : %s\n",pData);
}
sleep(10);
pthread_mutex_lock(&g_mutex);
threadFinished = 1;
pthread_mutex_unlock(&g_mutex);
return "This is thread message !"; /* No need to cast here in C, as opposed to C++. */
}
You should added error checking to all library calls in case a failure would influence the remaining execution.
I have this code, I am trying to create n threads, Do some work in each thread, and then reap each thread. If n thread is even, use detach, and if odd, use join,
When i run the program, it first prints out Successfully reaped thread, then doing working, then successfully reaped thread... looks like i have some synchronization issues
Do I even need to use Mutex?
Can anyone help me with getting everything running in the right order?
Thank you
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t lock;
void *dowork(){
//Do whatever needs to be done in each thread here
pthread_mutex_lock(&lock);
long tid = (long) pthread_self();
printf("Doing Work ...for %ld\n",tid);
pthread_mutex_unlock(&lock);
//pthread_exit(NULL);
return;
}
void spawn(int n){
if (pthread_mutex_init(&lock, NULL) != 0)
{
printf("\n mutex init failed\n");
exit (1);
}
int i=0;
//pthread_t * thread = malloc(sizeof(pthread_t)*n);
pthread_t threads[n];
while (i<n) {
if(pthread_create(&(threads[i]), NULL, dowork, NULL) != 0){
printf ("Create pthread error!\n");
exit (1);
}
i++;
}//End of while
// Wait for threads to complete //
i = 0;
while (i<n)
{
int success = -1;
if(i%2 == 0){
success=pthread_detach(threads[i]);
}
else{
success=pthread_join(threads[i], NULL);
}
if(success==0)
printf("Succesfully reaped thread\n");
i++;
}
pthread_mutex_destroy(&lock);
}
int main() {
spawn(5);
}
The program is supposed to create x amount of threads based on the arguments that are passed to it. argv[1] is the amount main is supposed to sleep, argv[2] is the number of propucer threads, and argv[3] is the number of consumer threads. The program compiles fine and the command I have been using to run it is: program 10 1 1.
I've been staring at this code for a while now and I can't seem to find what is causing the segmentation fault. Maybe a second set of eyes will be able to pick it quickly.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>
#include "buffer.h"
void *producer(void *);
void *consumer(void *);
// Semaphores
sem_t empty;
sem_t full;
pthread_mutex_t mutex;
// Buffer
int placed = 0;
buffer_item buffer[BUFFER_SIZE];
int insert_item(buffer_item item){
/* INSERT ITEM INTO BUFFER */
int z;
sem_wait(&empty);
//mutex lock
z = pthread_mutex_lock(&mutex);
if (z != 0){
return -1;
}
buffer[placed] = item;
//mutex unlock
z = pthread_mutex_unlock(&mutex);
if (z != 0){
return -1;
}
sem_post(&full);
placed++;
printf("producer produced %d\n", item);
}
int remove_item(buffer_item *item){
/* REMOVE ITEM FROM BUFFER */
int m;
placed--;
sem_wait(&full);
//mutex lock
m = pthread_mutex_lock(&mutex);
if (m != 0){
return -1;
}
buffer[placed] = -1;
//mutex unlock
m = pthread_mutex_unlock(&mutex);
if (m != 0){
return -1;
}
sem_post(&empty);
printf("consumer consumed %d\n", rand);
return 0;
}
// Main
int main(int argc, char *argv[]){
int sleepNum, pThreadNum, cThreadNum, p;
sleepNum = atoi(argv[1]);
pThreadNum = atoi(argv[2]);
cThreadNum = atoi(argv[3]);
// Initialize Semaphores & mutex
sem_init(&empty, 0, BUFFER_SIZE);
sem_init(&full, 0, 0);
pthread_mutex_init(&mutex, NULL);
// Create producer thread
pthread_t tid[pThreadNum];
int g=pThreadNum-1;
while(g >= 0){
p = pthread_create(&tid[g], NULL, producer, NULL);
g--;
}
printf("created prod thread");
// Create consumer thread
pthread_t kid[cThreadNum];
g = cThreadNum-1;
while(g >= 0){
p = pthread_create(&kid[g], NULL, consumer, NULL);
g--;
}
// Sleep for argv[0]
sleep(sleepNum);
// Destroy mutex & semaphores
sem_destroy(&empty);
sem_destroy(&full);
p = pthread_mutex_destroy(&mutex);
// Exit
exit(0);
}
// Producer
void *producer(void *param){
buffer_item rand;
unsigned int *seed;
int b;
while(1){
sleep(2);
rand = rand_r(seed);
b = insert_item(rand);
if (b < 0){
printf("Error producing item.");
}
}
}
// Consumer
void *consumer(void *param){
buffer_item rand;
int d;
while(1){
sleep(2);
d = remove_item(&rand);
if (d < 0){
printf("Error removing item");
}
}
}
Thanks in advance!
On Unix, you can get the backtrace from a segmentation fault by dumping core and examing the corefile in gdb.
$ ulimit -c <max core file size in 1k blocks>
$ gdb program core
gdb> bt
should dump the backtrace, and you can see exactly which line segfaulted.
In the producer you are using an uninitialized pointer. Try allocating some memory for it using malloc. I'm not explaining exactly what it is because you tagged this as homework.
Also don't rely on the output from printf statements to tell you where the program got to when using threads. It helps if you flush the output stream explicitly after each printf, then you'll almost get an idea of the right sequence of events.
compile your program with -g, as gcc -g program.c -lpthread
then
gdb a.out
set breakpoint as
b main
start
and then use s for step by step execution and see where it is falling.
As someone already mentioned that your producer function has uninitialized pointer unsigned int *seed;
also this program has lost wake-up problem associated with it, along with normal unlocking problem ( as in function insert item, what if insert_item thread context-switched before doing placed++. )
Here's a great article for finding the causes of segfaults.
Link
Link mirrored here, in case it ever goes down.... you never know.