I try to test one application which will run several threads with different priority , so the following is my test ap , run in linux x86_64 :
pthread_spinlock_t orderspinlock ;
int iGlbCnt=0 ;
void * donothing(void *arg)
{
pthread_attr_t attr;
pthread_attr_init (&attr);
//int s = pthread_attr_setinheritsched (&attr, PTHREAD_INHERIT_SCHED );
int s = pthread_attr_setinheritsched (&attr, PTHREAD_EXPLICIT_SCHED );
if( s != 0 ){
printf("pthread_attr_setinheritsched error \n");
exit(0) ;
}
int ipriority = (int)(long) arg ;
const char *sched_policy[] = {
"SCHED_OTHER",
"SCHED_FIFO",
"SCHED_RR",
"SCHED_BATCH"
};
struct sched_param sp = {
.sched_priority = ipriority
};
pid_t pid = getpid();
printf("pid=(%d)\n",pid);
sched_setscheduler(pid, SCHED_RR, &sp);
printf("Scheduler Policy is %s.\n", sched_policy[sched_getscheduler(pid)]);
pthread_detach(pthread_self());
int icnt=0;
while(1){
usleep( 1 ) ;
pthread_spin_lock(&orderspinlock) ;
iGlbCnt++ ;
pthread_spin_unlock(&orderspinlock) ;
if( ++icnt > 10000000 )
break;
}
printf("thread done...(%d)\n",iGlbCnt);
}
int main(int argc, char **argv)
{
pthread_spin_init(&orderspinlock, 0);
pthread_attr_t attr;
pthread_attr_init (&attr);
//int s = pthread_attr_setinheritsched (&attr, PTHREAD_INHERIT_SCHED );
int s = pthread_attr_setinheritsched (&attr, PTHREAD_EXPLICIT_SCHED );
if( s != 0 ){
printf("pthread_attr_setinheritsched error \n");
exit(0) ;
}
pthread_t tid;
pthread_create(&tid, NULL, &donothing, (void *)(long) 80);
pthread_create(&tid, NULL, &donothing, (void *)(long) 10);
while( 1 )
sleep( 5 ) ;
}
and g++ --std=c++11 y.cpp -pthread -o y.exe
run :
sudo chrt -r -v 66 ./y.exe
another terminal watch the threads by
top -H -p `pidof y.exe`
I see the threads PR are -67 , -67 , -11 , after both donothing threads die ,
the main thread PR = -11 , What should I do so that all three threads
priority are -81 , -11 , -67 and the main thread keep in -67 to the end ?!
Edit :
int policy = 2 ;
s = pthread_setschedparam(pthread_self(),policy,&sp) ;
instead of :
pid_t pid = getpid();
sched_setscheduler(pid, SCHED_RR, &sp);
look work fine to me .
Related
I am creating my Operating system project in which this is my code,
I am using a Linux operating system and I when I am compiling my code, the pthread_create() function is showing an error. The error is related to void return type.
#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#
define LEFT(PhilNum + 4) % 5# define RIGHT(PhilNum + 1) % 5
enum s {
EATING,
HUNGRY,
THINKING
};
struct Philosopher {
char * name;
int id;
};
struct Philosopher P[5] = {
{
"Professor A",
0
},
{
"Professor B",
1
},
{
"Professor C",
2
},
{
"Professor D",
3
},
{
"Professor E",
4
}
};
int ProcessCurrantState[5];
sem_t MUTEX;
sem_t Chop[5];
void CheckAvailability(int PhilNum) {
if (ProcessCurrantState[LEFT] != EATING && ProcessCurrantState[RIGHT] != EATING) {
// ProcessCurrantState that eating
ProcessCurrantState[PhilNum] = EATING;
sleep(2);
printf("--------------------------------------------------------\n");
printf("| Philosopher %s ,id : %d | Picking up Chopsticks %d and %d .| \n", P[PhilNum].name,
PhilNum + 1, LEFT + 1, PhilNum + 1);
printf("--------------------------------------------------------\n");
printf("--------------------------------------------------------\n");
printf("Philosopher %s , id : %d | is Eating .\n", P[PhilNum].name, PhilNum + 1);
printf("--------------------------------------------------------\n");
sem_post( & Chop[PhilNum]);
}
}
// take up chopsticks
void PickUpChopSticks(int PhilNum) {
sem_wait( & MUTEX);
// ProcessCurrantState that hungry
ProcessCurrantState[PhilNum] = HUNGRY;
printf("--------------------------------------------------------\n");
printf(" | Philosopher %s , id : %d | is Hungry . |\n", P[PhilNum].name, PhilNum + 1);
printf("--------------------------------------------------------\n");
// eat if neighbours are not eating
CheckAvailability(PhilNum);
sem_post( & MUTEX);
// if unable to eat wait to be signalled
sem_wait( & Chop[PhilNum]);
sleep(1);
}
// put down chopsticks
void PutChopsticksDown(int PhilNum) {
sem_wait( & MUTEX);
// ProcessCurrantState that thinking
ProcessCurrantState[PhilNum] = THINKING;
printf("---------------------------------------------------------\n");
printf("| Philosopher %s , id : %d | puting down Chopsticks %d and %d .|\n", P[PhilNum].name,
PhilNum + 1, LEFT + 1, PhilNum + 1);
printf("--------------------------------------------------------\n");
printf("| Philosopher %s , id : %d | is thinking . | \n", P[PhilNum].name, PhilNum + 1);
printf("--------------------------------------------------------\n");
CheckAvailability(LEFT);
CheckAvailability(RIGHT);
sem_post( & MUTEX);
}
void * philospher(void * num) {
while (1) {
int i = (int * ) num;
sleep(1);
PickUpChopSticks(i);
sleep(0);
PutChopsticksDown(i);
}
}
int main() {
int i;
pthread_t Thread[5];
// initialize the semaphores
sem_init( & MUTEX, 0, 1);
for (i = 0; i < 5; i++) {
sem_init( & Chop[i], 0, 0);
}
// create philosopher processes
for (i = 0; i < 5; i++) {
pthread_create( & Thread[i], NULL, philospher, (void * ) P[i].id);
printf("--------------------------------------------------------\n");
printf("| Philosopher %s , id : %d | is thinking\n . |", P[i].name, i + 1);
printf("--------------------------------------------------------\n");
}
for (i = 0; i < 5; i++)
pthread_join(Thread[i], NULL);
}
and I am getting this error while running
main.cpp: In function ‘void* philospher(void*)’:
main.cpp:97:21: error: invalid conversion from ‘int*’ to ‘int’ [-fpermissive]
int i = (int *)num;
In pthread_create it casts int to void*. The reverse conversion you need is void* to int:
int i = (int)num;
In C++ code you may like to use std::thread instead of pthread_create, so that you can pass thread arguments without casting. E.g.:
void philospher(int num);
// ...
std::thread Thread[5];
// ...
Thread[i] = std::thread(philospher, P[i].id);
//
for(auto& t : Thread)
t.join();
After terminating each thread using the below program, I need to print the remaining threads with ids every time, for which I am using GetExitCodeThread function but it is returning some garbage value.What could I be doing wrong?Also, how to print the remaining threads after getting the exitCode correct?
#define NUM_THREADS 10
#include <windows.h>
#include <stdio.h>
#include <process.h>
typedef struct
{
int Id;
HANDLE hTerminate;
} ThreadArgs;
unsigned _stdcall ThreadFunc( void *pArgs )
{
LPDWORD exitCode;
HANDLE hTerminate = ((ThreadArgs *)pArgs)->hTerminate;
int id = ((ThreadArgs *)pArgs)->Id;
// run until we are told to terminate while (1)
while(1)
{
// Check to see if we should terminate
if (WaitForSingleObject(hTerminate, 0) == WAIT_OBJECT_0)
{
// Terminate Thread - we call ResetEvent to
// return the terminate thread to its non-
// signaled state, then exit the while() loop
printf ("Terminating Thread %d\n", id);
GetExitCodeThread(hTerminate,exitCode);
printf("%d",exitCode);
ResetEvent(hTerminate);
break;
}
// we can do our work now ...
// simulate the case that it takes
// to do the work the thread has to do
Sleep(1000);
}
_endthreadex(0);
return 0;
}
int main(int argc, char* argv[])
{
int i=0;
unsigned int threadID[NUM_THREADS];
HANDLE hThread[NUM_THREADS];
ThreadArgs threadArgs[NUM_THREADS];
// Create 10 threads
printf("Total number of threads= %d\n", NUM_THREADS);
for (i = 0; i < NUM_THREADS;i++)
{
printf("Thread number %d \n",i);
}
for (int i = 0; i<NUM_THREADS;i++)
{
threadArgs[i].Id = i;
threadArgs[i].hTerminate = CreateEvent(NULL,TRUE,FALSE,NULL);
hThread[i] = (HANDLE)_beginthreadex(NULL,0,&ThreadFunc,&threadArgs[i], 0, &threadID[i]);
}
printf("To kill a thread (gracefully), press 0-9, "" then <Enter>. \n");
printf("Press any other key to exit.\n");
while (1)
{
int c = getc(stdin);
if (c == '\n')
continue;
if (c < '0' || c > '9')
break;
SetEvent(threadArgs[c -'0'].hTerminate);
}
return 0;
}
GetExitCodeThread() expects a HANDLE to a thread object, but you are passing it a HANDLE to an event object instead. You are also passing it an uninitialized pointer to write the exit code to. As such, GetExitCodeThread() is goes to fail with an error that you are ignoring, and the exit code will not be assigned any meaningful value.
Not that it matters, because GetExitCodeThread() is useless to call inside a thread that is still running, it will set the exit code to STILL_ACTIVE. You are supposed to call GetExitCodeThread() in a different thread than the one that is being terminated.
Try something more like this instead:
#include <windows.h>
#include <stdio.h>
#include <process.h>
#define MAX_THREADS 10
typedef struct
{
int Id;
DWORD dwThreadId;
HANDLE hThread;
HANDLE hTerminate;
} ThreadArgs;
unsigned __stdcall ThreadFunc( void *arg )
{
ThreadArgs *pArgs = (ThreadArgs *) arg;
// run until we are told to terminate while (1)
while(1)
{
// Check to see if we should terminate
if (WaitForSingleObject(pArgs->hTerminate, 0) == WAIT_OBJECT_0)
{
// Terminate Thread - exit the while() loop
printf ("Thread %d terminate signal detected\n", pArgs->Id);
break;
}
// we can do our work now ...
// simulate the case that it takes
// to do the work the thread has to do
Sleep(1000);
}
return 0;
}
int main(int argc, char* argv[])
{
int i;
ThreadArgs threadArgs[MAX_THREADS];
int numThreadsRunning = 0;
memset(&ThreadArgs, 0, sizeof(ThreadArgs));
// Create 10 threads
printf("Creating %d threads\n", MAX_THREADS);
for (i = 0; i < MAX_THREADS; ++i)
{
printf("Thread number %d: ", i);
threadArgs[i].Id = i;
threadArgs[i].hTerminate = CreateEvent(NULL, TRUE, FALSE, NULL);
threadArgs[i].hThread = (HANDLE) _beginthreadex(NULL, 0, &ThreadFunc, &threadArgs[i], 0, &threadArgs[i].dwThreadId);
if (threadArgs[i].hThread != NULL)
{
printf("Created\n");
++numThreadsRunning;
}
else
printf("Not Created!\n");
}
printf("Threads running: %d\n", numThreadsRunning);
printf("To kill a thread (gracefully), press 0-%d, then <Enter>.\n", MAX_THREADS-1);
printf("Press any other key to exit.\n");
while (1)
{
int c = getc(stdin);
if (c == '\n')
continue;
if ((c < '0') || (c > '9'))
break;
int id = c - '0';
if (threadArgs[id].hThread != NULL)
{
printf ("Signaling Thread %d to Terminate\n", id);
SetEvent(threadArgs[id].hTerminate);
WaitForSingleObject(threadArgs[id].hThread, INFINITE);
DWORD exitCode = 0;
GetExitCodeThread(threadArgs[id].hThread, &exitCode);
CloseHandle(threadArgs[id].hThread);
threadArgs[id].hThread = NULL;
printf ("Thread %d Terminated. Exit Code: %u\n", id, exitCode);
--numThreadsRunning;
printf ("Threads still running: %d\n", numThreadsRunning);
}
else
printf ("Thread %d is not running\n", id);
}
if (numThreadsRunning > 0)
{
printf ("Signaling remaining Threads to Terminate\n");
HANDLE hThreads[MAX_THREADS];
DWORD numThreads = 0;
for (i = 0; i < MAX_THREADS; ++i)
{
if (threadArgs[i].hThread != NULL)
{
hThreads[numThreads] = threadArgs[i].hThread;
++numThreads;
SetEvent(threadArgs[i].hTerminate);
}
}
WaitForMultipleObjects(numThreads, hThreads, TRUE, INFINITE);
for (i = 0; i < MAX_THREADS; ++i)
{
if (hThreads[i].hThread)
CloseHandle(hThreads[i].hThread);
if (hThreads[i].hTerminate)
CloseHandle(hThreads[i].hTerminate);
}
printf ("Threads Terminated\n");
}
return 0;
}
Have a look at this msdn article:
Traversing the Thread List
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686852(v=vs.85).aspx
There is sample code on how to list the threads for a process.
~snip
#include <windows.h>
#include <tlhelp32.h>
#include <tchar.h>
// Forward declarations:
BOOL ListProcessThreads( DWORD dwOwnerPID );
void printError( TCHAR* msg );
int main( void )
{
ListProcessThreads(GetCurrentProcessId() );
return 0;
}
BOOL ListProcessThreads( DWORD dwOwnerPID )
{
HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
THREADENTRY32 te32;
// Take a snapshot of all running threads
hThreadSnap = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
if( hThreadSnap == INVALID_HANDLE_VALUE )
return( FALSE );
// Fill in the size of the structure before using it.
te32.dwSize = sizeof(THREADENTRY32 );
// Retrieve information about the first thread,
// and exit if unsuccessful
if( !Thread32First( hThreadSnap, &te32 ) )
{
printError( TEXT("Thread32First") ); // Show cause of failure
CloseHandle( hThreadSnap ); // Must clean up the snapshot object!
return( FALSE );
}
// Now walk the thread list of the system,
// and display information about each thread
// associated with the specified process
do
{
if( te32.th32OwnerProcessID == dwOwnerPID )
{
_tprintf( TEXT("\n THREAD ID = 0x%08X"), te32.th32ThreadID );
_tprintf( TEXT("\n base priority = %d"), te32.tpBasePri );
_tprintf( TEXT("\n delta priority = %d"), te32.tpDeltaPri );
}
} while( Thread32Next(hThreadSnap, &te32 ) );
_tprintf( TEXT("\n"));
// Don't forget to clean up the snapshot object.
CloseHandle( hThreadSnap );
return( TRUE );
}
void printError( TCHAR* msg )
{
DWORD eNum;
TCHAR sysMsg[256];
TCHAR* p;
eNum = GetLastError( );
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, eNum,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
sysMsg, 256, NULL );
// Trim the end of the line and terminate it with a null
p = sysMsg;
while( ( *p > 31 ) || ( *p == 9 ) )
++p;
do { *p-- = 0; } while( ( p >= sysMsg ) &&
( ( *p == '.' ) || ( *p < 33 ) ) );
// Display the message
_tprintf( TEXT("\n WARNING: %s failed with error %d (%s)"), msg, eNum, sysMsg );
}
I have the following source compiled by g++ 4.8.2 :
g++ --std=c++11 testx.cpp -pthread -lrt -O2 -o testx.exe
g++ --std=c++11 testx.cpp -pthread -lrt -o testy.exe
layout.h :
#pragma once
typedef struct DBInfo_
{
volatile int seqno ;
char groupname[32] ;
char action[32] ;
int booklayer ;
} DBInfo ;
#define DBARRAYSIZE 100
static DBInfo *conf;
#define STATE_FILE "/strategy2/test.shared"
testx.cpp :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/file.h>
#include <ctype.h>
#include <pthread.h>
#include <sys/stat.h>
#include <assert.h>
#include "layout.h"
int g_DBSharedMemIdx = 0 ;
volatile int iGlbErrorSeqLock = 0 ;
void create_shmem(void)
{
int shm_fd;
if((shm_fd = shm_open(STATE_FILE, (O_CREAT | O_EXCL | O_RDWR),
(S_IREAD | S_IWRITE))) > 0 ) {
printf("O_CREAT | O_EXCL | O_RDWR \n"); /* We are the first instance */
}
else if((shm_fd = shm_open(STATE_FILE, (O_CREAT | O_RDWR),
(S_IREAD | S_IWRITE))) < 0)
{
printf("Could not create shm object. \n");
exit( 0 ) ;
}
int iTotalByte = sizeof(DBInfo)*DBARRAYSIZE ;
ftruncate(shm_fd, iTotalByte );
conf = (DBInfo*) mmap(0, iTotalByte , (PROT_READ | PROT_WRITE), MAP_SHARED, shm_fd, 0) ;
if(conf == MAP_FAILED)
{
printf(" mmap error ....\n") ;
exit( 0 ) ;
}
g_DBSharedMemIdx = 0 ;
(conf+g_DBSharedMemIdx)->seqno = 0 ;
strcpy( (conf+g_DBSharedMemIdx)->groupname,"" ) ;
strcpy( (conf+g_DBSharedMemIdx)->action,"" ) ;
(conf+g_DBSharedMemIdx)->booklayer = 0 ;
}//create_shmem
int getDBInfo(DBInfo& pDBInfo)
{
if( pDBInfo.seqno == (conf+g_DBSharedMemIdx)->seqno)
return 0 ;
volatile int ilocalseqno1 = 0 , ilocalseqno2 = 0 ;
volatile int icnt=0;
while( 1 ){
icnt++ ;
if( icnt >= 10000 ){
iGlbErrorSeqLock = 1 ;
break ;
}
ilocalseqno1 = (conf+g_DBSharedMemIdx)->seqno ;
if( ilocalseqno1 % 2 ){
printf("***************************************************************************** \n");
continue;
}
strcpy( pDBInfo.action,(conf+g_DBSharedMemIdx)->action ) ;
pDBInfo.booklayer = (conf+g_DBSharedMemIdx)->booklayer ;
ilocalseqno2 = (conf+g_DBSharedMemIdx)->seqno ;
if( ilocalseqno1 != ilocalseqno2 ){
printf("***************************************************************************** \n");
continue;
}
pDBInfo.seqno = ilocalseqno2 ;
break ;
} //while
if( iGlbErrorSeqLock == 1 )
return -1 ;
return 1 ;
}//getDBInfo
void *ThreadONE(void *param)
{
printf("TestThread...(%p)\n",param) ;
pthread_detach(pthread_self());
while( 1 ){
(conf+g_DBSharedMemIdx)->seqno++ ;
strcpy( (conf+g_DBSharedMemIdx)->groupname,"group1" ) ;
strcpy( (conf+g_DBSharedMemIdx)->action,"RUN" ) ;
(conf+g_DBSharedMemIdx)->booklayer = 3 ;
if( (conf+g_DBSharedMemIdx)->seqno % 2 == 1 )
(conf+g_DBSharedMemIdx)->seqno++ ;
usleep( 1 ) ;
}//while
}//ThreadONE
void *ThreadTWO(void *param)
{
DBInfo pDBInfo ;
printf("TestThread...(%p)\n",param) ;
pthread_detach(pthread_self());
int icnt = 0 ;
while( 1 ){
int iret = getDBInfo(pDBInfo);
if( iret < 0 ){
printf("iGlbErrorSeqLock happened \n") ;
assert( iGlbErrorSeqLock == 100 );
}else if(iret == 1){
icnt++ ;
//printf("icnt=(%d)\n",icnt);
}
usleep( 1 ) ;
}//while
}//ThreadTWO
int main(int argc, char** argv)
{
create_shmem();
sleep( 1 ) ;
pthread_t tid ;
pthread_create(&tid , NULL, ThreadONE, (void*)(long)3);
pthread_create(&tid , NULL, ThreadTWO, (void*)(long)3);
while( 1 )
sleep( 5 ) ;
} //main
testy.exe(compiled without -O2) run will see "**************" 2 times per second ,
testx.exe(compiled with -O2) run will see "***********" not quite easy .
I have this test because in my original source , sometimes call function
like getDBInfo will be trapped in endless loop if compiled with -O2,
and it will be fine without -O2 , so I am curious what compiler do in
getDBInfo function and what should I do according to it .
I have recently testing queue with hazard pointer application as below :
https://github.com/chergert/dukes_of_hazard
I have noticed that RES raise quite fast in my own test ap ,
MEMORY-ERROR: [30770]: GSlice: failed to allocate 120 bytes (alignment: 128): Cannot allocate memory
happened in the end , the ap has 5 threads to enqueue , 5 threads to dequeue and then
send to 5 socket server each thread , like following :
#include "lf-queue.h"
typedef struct People_
{
int age ;
char name[16] ;
double income ;
} People ;
#define NUM 20000000
LfQueue *q ;
int GlbCnt,GlbRow ;
int iConn[5] ;
int main()
{
q = lf_queue_new();
g_thread_init(NULL);
if(DoConnect() != 1)
{
printf("Error in connect server .exe , port=5566,5567,5568,5569,5570 ! \n") ;
exit(0) ;
}
pthread_t tid1[5],tid2[5];
int icnt1[5] = {0,1,2,3,4} ;
int icnt2[5] = {0,1,2,3,4} ;
void *func1(void *);
void *func2(void *);
for(int idx=0;idx<5;idx++)
{
pthread_create(&tid1[idx], NULL, &func1 , (void *) icnt1[idx] );
pthread_create(&tid2[idx], NULL, &func2 , (void *) icnt2[idx] );
}
while(1){
printf("Done(%d)\n",GlbCnt) ;
sleep(1) ;
}
} //main
void *func1(void * inum)
{
int ithread = (long)(int) inum ;
pthread_detach(pthread_self());
People* p ;
while(1){
for(int idx=0;idx<NUM;idx++){
usleep(1) ;
p = (People *) malloc( sizeof(People) ) ;
p->age = __sync_add_and_fetch(&GlbRow,1) ;
sprintf(p->name,"%s%08d","NAME",p->age ) ;
p->income = p->age * 1.0 ;
lf_queue_enqueue(q,p) ;
}
break ;
} //while
}
void *func2(void * inum)
{
int ithread = (long)(int) inum ;
pthread_detach(pthread_self());
People* p ;
while(1){
usleep(1) ;
p = (People *) lf_queue_dequeue(q) ;;
if(p){
char line[128]={0} ;
sprintf(line,"%010d|%s|%010.0f|",p->age,p->name,p->income) ;
if (send(iConn[ithread],line,35,MSG_NOSIGNAL)<0){
printf("send error \n");
exit( 0 ) ;
}
__sync_add_and_fetch(&GlbCnt,1) ;
free(p) ;
}
} //while
}
I need 2 threads: TC and TS, such that they are composed in two main sections each accessing shared data and the threads must to be synchronized. The synchronization should be like this:
The red codes are working with shared data U, but get U can be placed before the dashed rectangle on the TS thread, riht side.
The Xcurrent can be in TC or in TS the tasks, but is a shared hardware with send Ucurrent and get must be right after send was finished.
A dead lock appears and I can't figure out an elegant solution.
Thread TS:
#include <stdio.h> /* printf, scanf, NULL */
#include <stdlib.h> /* malloc, free, rand */
#define _USE_MATH_DEFINES
#include <math.h>
#include <windows.h>
#include <pthread.h>
#include <time.h>
// CRLT-C var
static int stop = 0;
// TIMEING vars
__int64 frequencyT, startT, endT = 0;
double baseAngleLast;
double pendulAngleLast;
// THREADING vars
bool startedS = false, Usent = false;
double * Ucmd;
pthread_mutex_t mutexU = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutexBoard = PTHREAD_MUTEX_INITIALIZER;
unsigned int Ulenght = 6;
pthread_cond_t signal_to_read_state = PTHREAD_COND_INITIALIZER;
pthread_cond_t signal_to_read_cmd = PTHREAD_COND_INITIALIZER;
DWORD sleepTime = 30; // in milliseconds
int currentState = 3;
void *sendingCMD(void * )
{
double * U_tmp;
U_tmp = (double*)malloc(sizeof(double)*Ulenght);
startedS = true;
printf("Sin\n");
while (stop == 0)
{
printf("Smu-\n");
//get U
pthread_mutex_lock( &mutexU );
printf("Smu..\n");
pthread_cond_wait(&signal_to_read_cmd, &mutexU);
memcpy(U_tmp,Ucmd,sizeof(double)*Ulenght);
pthread_mutex_unlock( &mutexU );
printf("Smu+\n");
pthread_mutex_lock( &mutexBoard );
for (unsigned int i = 0; i<Ulenght; i++)
{
//send CMD signal
printf("%f ", U_tmp[i]);
if (i == Ulenght -1) printf("\n");
}
Sleep(sleepTime); // miliseconds
currentState = currentState + 1;
pthread_cond_signal(&signal_to_read_state);
pthread_mutex_unlock( &mutexBoard );
printf("Smb\n");
}
printf("Task S terminated. \n");
return (NULL);
}
void *computingU(void *)
{
double * U_tmp;
U_tmp = (double*)malloc(sizeof(double)*Ulenght);
int currentStateTMP =0;
bool fisrtLoop = true;
printf("Uin\n");
while (stop == 0)
{
printf("Umb- \n");
// get current state
pthread_mutex_lock( &mutexBoard );
if (!fisrtLoop)
{
printf("UmbFalse \n");
pthread_cond_wait(&signal_to_read_state, &mutexBoard);
}
else
{
printf("UmbTrue \n");
fisrtLoop=false;
}
currentStateTMP =currentState;
pthread_mutex_unlock( &mutexBoard );
printf("Umb+ \n");
pthread_mutex_lock( &mutexU );
for (unsigned int i=0;i<Ulenght;i++)
{
Ucmd[i] = Ucmd[i]+ (double)currentStateTMP/i;
}
pthread_cond_signal(&signal_to_read_cmd);
pthread_mutex_unlock( &mutexU );
printf("Umu\n");
}
return (NULL);
}
void signal_handler(int signal)
{
stop = 1;
}
int main(int argc, char* argv[])
{
//initializing output buffer to 0[V]
Ucmd= (double*)malloc(sizeof(double)*Ulenght);
for (unsigned int i=0;i<Ulenght;i++)
Ucmd[i] = 0;
//init threads
int rc1, rc2;
pthread_t threadU, threadS;
/* Create independent threads each of which will execute functionC */
if( (rc1=pthread_create( &threadU, NULL, &computingU, NULL)) ) {
printf("ThreadU creation failed: %d\n", rc1);
}
if( (rc2=pthread_create( &threadS, NULL, &sendingCMD, NULL)) )
{
printf("ThreadS creation failed: %d\n", rc2);
}
while (stop == 0);
printf("Main terminated, closing board in 10ms. \n");
Sleep(10);
return 0;
}
The blocking appears at:
TC at pthread_cond_wait(&signal_to_read_state, &mutexBoard);
TS at pthread_cond_wait(&signal_to_read_cmd, &mutexU);
btw why dose not recognize stackoverflow the code segment I pasted above in case i copy paste from a VS2010?