Output of semaphore values - c

Here's my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
sem_t s1, s2;
pthread_t foo_tid, bar_tid;
void *foo(void*) {
while(1) {
sem_wait(&s1);
printf("HI ");
sem_post(&s2);
}
}
void *bar(void*) {
while(1) {
sem_wait(&s2);
printf("HO ");
sem_post(&s1);
}
}
int main() {
sem_init(&s1, 0, 0);
sem_getvalue(&s1, &foo_tid);
sem_init(&s2, 0, 0);
sem_getvalue(&s2, &bar_tid);
pthread_create(&foo_tid, NULL, foo, NULL);
pthread_create(&bar_tid, NULL, bar, NULL);
return 0;
}
I'm trying to get the output of the semaphores s1 and s2. But I keep getting these errors:
sema.c: In function 'main':
sema.c:29:3: warning: passing argument 2 of 'sem_getvalue' from incompatible pointer type [enabled by default]
In file included from sema.c:6:0:
/usr/include/semaphore.h:72:12: note: expected 'int * __restrict__' but argument is of type 'pthread_t *'
sema.c:31:3: warning: passing argument 2 of 'sem_getvalue' from incompatible pointer type [enabled by default]
In file included from sema.c:6:0:
/usr/include/semaphore.h:72:12: note: expected 'int * __restrict__' but argument is of type 'pthread_t *'`
I just haven not been able to get rid of this error. If anyone could help me out with this, that'd be greatly appreciated!

From sem_getvalue, values should be int :
Declare int s1_val, s2_val;
sem_init(&s1, 0, 0);
sem_getvalue(&s1, &s1_val);
sem_init(&s2, 0, 0);
sem_getvalue(&s2, &s2_val);

The second parameter is expected to be a pointer to int, where as you are passing in the address of a pthread_t. A pthread_t is not an int on your system.

Related

Getting warning of passing argument 3 of ‘pthread_create’ from incompatible pointer type [-Wincompatible-pointer-types]

I am running the below code and it is working fine but still it is giving some warning which i don't understand. Can someone please explain this to me ? Thanks
#include <stdio.h>
#include <pthread.h>
void* the_thread_func(double data_for_thread[]) {
/* Do something here? */
for(int i=0;i<3;i++){
double sum = sum + data_for_thread[i];
printf("The sum done by the_thread_func() is = %f\n",sum);
}
return NULL;
}
int main() {
printf("This is the main() function starting.\n");
double data_for_thread[3];
data_for_thread[0] = 5.7;
data_for_thread[1] = 9.2;
data_for_thread[2] = 1.6;
/* Start thread. */
pthread_t thread;
printf("the main() function now calling pthread_create().\n");
pthread_create(&thread, NULL, the_thread_func, data_for_thread);
printf("This is the main() function after pthread_create()\n");
/* Do something here? */
for(int i=0;i<3;i++){
double sum = sum + data_for_thread[i];
printf("The sum done by main() is = %f\n",sum);
}
/* Wait for thread to finish. */
printf("the main() function now calling pthread_join().\n");
pthread_join(thread, NULL);
return 0;
}
warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type [-Wincompatible-pointer-types] pthread_create(&thread, NULL, the_thread_func, data_for_thread);
^~~~~~~~~~~~~~~
In file included from thread_data.c:2:0:
/usr/include/pthread.h:234:12: note: expected ‘void * (*)(void *)’ but argument is of type ‘void * (*)(double *)’
extern int pthread_create (pthread_t *__restrict __newthread,
According to the manual pthread_create needs to be given a function with this signature:
void* (*start_routine)(void*)
But you are passing it a function that accepts double*here:
void* the_thread_func(double data_for_thread[]) // decays to double*
I think you need to change the signature and cast the void*inside the function like this:
// accept void*
void* the_thread_func(void* vp) {
/* Do something here? */
double* data_for_thread = reinterpret_cast<double*>(vp); // cast here
for(int i=0;i<3;i++){
double sum = sum + data_for_thread[i];
printf("The sum done by the_thread_func() is = %f\n",sum);
}
return nullptr;
}

How to list info about processes using c in freebsd?

I want to list all processes in FreeBSD and I have this code below, which uses kvm, but it does not know what KVM_NO_FILES is, and I can't figure how to fix it. If there is another way of doing it, please do share.
#include <stdio.h>
#include <kvm.h>
#include <limits.h>
#include <sys/param.h>
#include <sys/sysctl.h>
int
main(void)
{
char errbuf[_POSIX2_LINE_MAX];
kvm_t *kernel = kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf);
int nentries = 0;
struct kinfo_proc *kinfo = kvm_getprocs(kernel, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &nentries);
int i;
for (i = 0; i < nentries; ++i) {
printf("%s\n", kinfo[i].p_comm);
}
return 0;
}
And I get this error:
root#freebsd:- # cc -lkvm main.c
main.c:11:53: error: use of undeclared identifier 'KVM_NO_FILES'
kvm_t *kernel = kvm_openfiles(NULL. NULL. NULL, HVM_NO_FILES, errbuf):
main.c:13:71: error: invalid application of 'sizeof' to an incomplete type
'struct kinfo_proc'
...= kvm_getprocs(kernel, HERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &nen...
/usr/include/kvM.h:72:8: note: forward declaration of 'struct kinfo_proc'
struct kinfo_proc;
main.c:18:29: error: subscript of pointer to incomplete type 'struct kinfo_proc'
printf("Xs\n", kinfolil.p_comm):
/usr/include/kvM.h:72:8: note: forward declaration of 'struct kinfo_proc'
struct kinfo_proc;
3 errors generated.

Using function pointer array in pthread_create - near initialization

EDIT: This has been answered with the help of John Bollinger and alk. Read their comments below! I've also included my revised code at the bottom on this original post for anyone searching to read
I'm trying to use an array of function pointers to send as the function argument in pthread_create but when I try to compile (using: "gcc -std=c99 P1.c -lpthread" I am getting the following errors:
P1.c:40:1: warning: initialization from incompatible pointer type [enabled by default]
func_ptr funcs[4] = {func0, func1, func2, func3};
P1.c:40:1: warning: (near initialization for 'funcs[0]') [enabled by default]
P1.c:40:1: warning: initialization from incompatible pointer type [enabled by default]
P1.c:40:1: warning: (near initialization for 'funcs[1]') [enabled by default]
P1.c:40:1: warning: initialization from incompatible pointer type [enabled by default]
P1.c:40:1: warning: (near initialization for 'funcs[2]') [enabled by default]
P1.c:40:1: warning: initialization from incompatible pointer type [enabled by default]
P1.c:40:1: warning: (near initialization for 'funcs[3]') [enabled by default]
I think it's an issue with my typedef declaration of my function pointer but I'm having trouble figuring out exactly what the issue is. Below is the relevant code snippet:
void func0()
{ printf("A"); }
void func1()
{ printf("B"); }
void func2()
{ printf("C"); }
void func3()
{ printf("D"); }
typedef void* (*func_ptr)(void *);
func_ptr funcs[4] = {func0, func1, func2, func3};
int main(int argc, char *argv[])
{
pthread_t pth[THREADCNT];
for(int i =0; i < THREADCNT; i++)
pthread_create(&pth[i], NULL, (funcs[i])(), NULL);
for(int i =0; i < THREADCNT; i++)
pthread_join(pth[i], NULL);
}
REVISED WORKING CODE BELOW
// changed these functions to void* with (void * pv) parameter to
// match the typedef (and also match the pthread_create parameter)
void* func0(void * pv)
{ printf("A"); }
void* func1(void * pv)
{ printf("B"); }
void* func2(void * pv)
{ printf("C"); }
void* func3(void * pv)
{ printf("D"); }
typedef void* (*func_ptr)(void *);
func_ptr funcs[4] = {func0, func1, func2, func3};
int main(int argc, char *argv[])
{
pthread_t pth[THREADCNT];
for(int i =0; i < THREADCNT; i++)
pthread_create(&pth[i], NULL, funcs[i], NULL);
// changed the funcs[i] because the function isn't called, the value is just passed as an argument
for(int i =0; i < THREADCNT; i++)
pthread_join(pth[i], NULL);
}
Change
void func0()
to be
void * func0(void * pv)
(same for the other three)
because that's the type the array is defined to hold, as well as the type pthread_create() expects.
Change
pthread_create(&pth[i], NULL, (funcs[i])(), NULL);
to be
pthread_create(&pth[i], NULL, funcs[i], NULL);
as you do not want to call funcs[i] but pass its value.

warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]

I'm using the following C code:
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
int main()
{
int file=0;
if((file=open("testfile.txt",O_RDONLY)) < -1)
return 1;
char buffer[19];
if(read(file,buffer,19) != 19) return 1;
printf("%s\n",buffer);
if(lseek(file,10,SEEK_SET) < 0) return 1;
if(read(file,buffer,19) != 19) return 1;
printf("%s\n",buffer);
return 0;
}
After compiling it produces a warning:
warning: incompatible implicit declaration of built-in
function ‘printf’ [enabled by default]
What does it mean and how do I appease the C compiler to not raise the warning?
You need to add #include <stdio.h> to the top of your file.

UNIX Shared memory and Semaphores in C

I started a week ago understanding and working with semaphores and shared memory, and actually created this program; the problem is I can't find anything wrong with it. I've been looking at it for hours and everything seems correct. The code compiles and i can create the build but when I execute it nothing happens.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <sys/fcntl.h>
#include <semaphore.h>
#define MAXCHILDS 4
#define MAX_SIZE 10
#define MAX_WRITES 4
typedef struct{
int m[MAX_SIZE][MAX_SIZE];
} matrix;
/*fork variables*/
pid_t child[MAXCHILDS];
/*semphores variables */
sem_t *empty, *full, * mutex;
/*share memory id*/
int shmid;
/*shared memory array pointer */
matrix * sh_mem;
/*pointer to matrix*/
int **p;
void init(){
/*create pointer to matrix*/
p = &sh_mem->m;
/*semaphores unlink and creation */
sem_unlink("EMPTY");
empty=sem_open("EMPTY",O_CREAT|O_EXCL,0700,MAX_WRITES);
sem_unlink("FULL");
full=sem_open("FULL",O_CREAT|O_EXCL,0700,0);
sem_unlink("MUTEX");
mutex=sem_open("MUTEX",O_CREAT|O_EXCL,0700,1);
/*initialize shared memory */
shmid = shmget(IPC_PRIVATE,sizeof(matrix),IPC_CREAT|0777);
/*map shared memory*/
sh_mem = (matrix*)shmat(shmid,NULL,0);
if(sh_mem== (matrix*)(-1)){
perror("shmat");
}
}
void writer(int ** m){
int i,k;
for(i = 0;i<MAX_SIZE;i++){
for(k= 0;k<MAX_SIZE;k++){
m[i][k] = 0;
}
}
}
void reader(int **m){
int i = 0;
int k = 0;
for(i = 0;i<MAX_SIZE;i++){
for(k= 0;k<MAX_SIZE;k++){
printf(m[i][k]);
}
printf("\n");
}
}
void terminate() {
sem_close(empty);
sem_close(full);
sem_close(mutex);
sem_unlink("EMPTY");
sem_unlink("FULL");
sem_unlink("MUTEX");
shmctl(shmid, IPC_RMID, NULL);
}
int main(int argc, char **argv)
{
int i;
init();
for(i = 0;i<MAXCHILDS;i++){
if ((child[i] = fork()) < 0) // error occured
{
perror("Fork Failed");
exit(1);
}
if ((child[i] = fork())==0){
writer(sh_mem->m);
exit(0);
}
}
/*father*/
reader(sh_mem->m);
wait(NULL);
terminate();
return 0;
}
The children are supposed to write the the matrix in shared memory, and the father is supposed to read the shared memory array and the print the matrix.
Can you help me with this? Thanks for the help ...
The primary error here is that reader and writer take a different type of argument than you're passing to them, as gcc -Wall points out:
test.c: In function ‘main’:
test.c:92:13: warning: passing argument 1 of ‘writer’ from incompatible pointer type [enabled by default]
test.c:49:6: note: expected ‘int **’ but argument is of type ‘int (*)[10]’
test.c:97:5: warning: passing argument 1 of ‘reader’ from incompatible pointer type [enabled by default]
test.c:58:6: note: expected ‘int **’ but argument is of type ‘int (*)[10]’
As provided, the program segfaulted in the parent and every child. When I changed the parameter type of reader and writer from int **m to int m[MAX_SIZE][MAX_SIZE] (along with the fixes below), the program ran successfully, as far as I can tell.
There are a number of other errors:
You need to #include <sys/wait.h>.
The global int **p isn't used and its initialization has the same type error as the reader and writer functions did.
The printf call in reader needs a format string; I used "%d ".
As Jonathan Leffler pointed out, you need to call fork() only once each time through the loop in main.
All but the last of those were highlighted by compiler warnings.
In studying why this program was failing, I also used strace -f to identify which syscalls and processes were actually busted. The semaphore-related syscalls, for example, appear to be returning successfully--although as Jonathan pointed out, you should check their return values for errors, because failing as early as possible makes it much easier to debug problems.

Resources