I have simple code:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <errno.h>
4 #include <string.h>
5 #include <sys/types.h>
6 #include <sys/ipc.h>
7 #include <sys/msg.h>
8
9 struct my_msgbuf {
10 long mtype;
11 char mtext[200];
12 };
13
14 int main(void){
15 struct my_msgbuf buf;
16 int msqid;
17 key_t key;
18
19 if((key = ftok("main.c", 'B')) == -1) {
20 perror("ftok"); exit(1);
21 }
22
23 if( (msqid = msgget(key, 0644 | IPC_CREAT)) == -1){
24 perror("msgget");
25 exit(1);
26 }
27
28 printf("Enter lines of text, ^D to quit:\n");
29 buf.mtype = 1;
30 while(fgets(buf.mtext, sizeof(buf.mtext), stdin) != NULL){
31 int len = strlen(buf.mtext);
32 if(buf.mtext[len-1] == '\n') buf.mtext[len-1] = '\0';
33 if(msgsnd(msqid, &buf, len+1,0) == -1){
34 perror("msgsnd");
35 }
36
37 }
38
39 if(msgctl(msqid, IPC_RMID, NULL) == -1){
40 perror("msgctl");
41 exit(1);
42 }
43
44 return 0;
45 }
and next step what i do:
gcc -o main main.c
next step run:
./main
and results:
msgget: no space left on device
how can I repair it? I'm working on university server (connecting by putty), it can be answer about this problem?
According to the man page, ENOSPC is the error for:
A message queue has to be created but the system limit for the maximum number of message queues (MSGMNI) would be exceeded.
If it's a server, it means there's too many message queues created by other users (not unlikely if this is some homework assignment and other students also work on the server). You can see the MSGMNI value with cat /proc/sys/kernel/msgmni. Only the admin can change it however.
Related
I have written a program to calculate a math expression with four basic operator.Now I want to write a program to generate expressions to test my calculate program,but there is a problem that there may be Zero division expression that will raise error.I tried to kill subprocess when it cause error,but I failed.I don't know how to avoid this problem.
#include <stdint.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <time.h>
20 #include <assert.h>
21 #include <string.h>
22
23 static char buf[65536] = {};
24 static char code_buf[65536 + 128] = {}; // a little larger than `buf`
25 static char *code_format =
26 "#include <stdio.h>\n"
27 "int main() { "
28
29 " unsigned result = %s; "
30 " printf(\"%%u\", result); "
31 " return 0; "
32 "}";
33
34 static int loc=0;//used in gen_rand_expr()
int main(int argc, char *argv[]) {
183 int seed = time(0);
184 srand(seed);
185 int loop = 1;
186 if (argc > 1) {
187 sscanf(argv[1], "%d", &loop);
188 }
189 int i;
190 for (i = 0; i < loop; i ++) {
191 gen_rand_expr(); //generate random expression
192
193 loc=0;
194 sprintf(code_buf, code_format, buf);
195
196 FILE *fp = fopen("/tmp/.code.c", "w");
197 assert(fp != NULL);
198 fputs(code_buf, fp);
199 fclose(fp);
200
201 int ret = system("gcc /tmp/.code.c -o /tmp/.expr");
202 if (ret != 0) continue;
203 fp = popen("/tmp/.expr", "r");
204 assert(fp != NULL);
205
206 int result;
207 fscanf(fp, "%d", &result);
208 pclose(fp);
209
210 printf("%u %s\n", result, buf);
211 }
212 return 0;
213 }
I'm new to C and I've been trying to create a program that takes a user input integer makes a sequence depending on whether the number is even or odd.
n / 2 if n is even
3 * n + 1 if n is odd
A new number will be computed until the sequence reaches 1. For example if a user inputs 35:
35, 106, 53, 160, 80, 40, 20, 10, 5, 16, 8, 4, 2, 1
For some reason my code doesn't work after the scan statement of the child process. I left my code and sample output below:
Code:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
pid_t pid;
int i = 0;
int j = 0;
/* fork a child process */
pid = fork();
if (pid < 0) { /* error occurred */
fprintf(stderr, "Fork Failed\n");
return 1;
}
else if (pid == 0) { /* child process */
printf("I am the child %d\n",pid);
printf("Enter a value: \n");
scanf("%d", i);
while (i < 0) {
printf("%d is not a positive integer. Please try again.\n", i);
printf("Enter a value: \n");
scanf("%d", i);
}
// can add a print i here
while (i != 1) {
if (i % 2 == 0) { // if the inputted number is even
j = i / 2;
}
else {
j = 3 * i + 1;
}
printf("%d", j);
}
}
else { /* parent process */
/* parent will wait for the child to complete */
printf("I am the parent %d\n",pid);
wait(NULL); // wait(NULL) will wait for the child process to complete and takes the status code of the child process as a parameter
printf("Child Complete\n");
}
return 0;
}
Output I'm getting on terminal in Linux (Debian):
oscreader#OSC:~/osc9e-src/ch3$ gcc newproc-posix.c
oscreader#OSC:~/osc9e-src/ch3$ ./a.out
I am the parent 16040
I am the child 0
Enter a value:
10
Child Complete
oscreader#OSC:~/osc9e-src/ch3$
Transferring comments into a semi-coherent answer.
Your calls to scanf() require a pointer argument; you give it an integer argument. Use scanf("%d", &i); — and it would be a good idea to check that scanf() returns 1 before testing the result.
My compiler told me about your bug. Why didn't your compiler do so too? Make sure you enable every warning you can! Your comment indicates that you're using gcc (or perhaps clang) — I routinely compile with:
gcc -std=c11 -O3 -g -Werror -Wall -Wextra -Wstrict-prototypes …
Indeed, for code from SO, I add -Wold-style-declarations -Wold-style-definitions to make sure functions are declared and defined properly. It's often a good idea to add -pedantic to avoid accidental use of GCC extensions.
In the loop, you don't need j — you should be changing and printing i instead.
cz17.c
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void)
{
int i = 0;
pid_t pid = fork();
if (pid < 0)
{
fprintf(stderr, "Fork Failed\n");
return 1;
}
else if (pid == 0)
{
printf("I am the child %d\n", pid);
printf("Enter a value: \n");
if (scanf("%d", &i) != 1)
{
fprintf(stderr, "failed to read an integer\n");
return 1;
}
while (i <= 0 || i > 1000000)
{
printf("value %d out of range 1..1000000. Try again.\n", i);
printf("Enter a value: \n");
if (scanf("%d", &i) != 1)
{
fprintf(stderr, "failed to read an integer\n");
return 1;
}
}
while (i != 1)
{
if (i % 2 == 0)
{
i = i / 2;
}
else
{
i = 3 * i + 1;
}
printf(" %d", i);
fflush(stdout);
}
putchar('\n');
}
else
{
printf("I am the parent of %d\n", pid);
int status;
int corpse = wait(&status);
printf("Child Complete (%d - 0x%.4X)\n", corpse, status);
}
return 0;
}
Compilation:
gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes cz17.c -o cz17
Sample output:
$ cz17
I am the parent of 41838
I am the child 0
Enter a value:
2346
1173 3520 1760 880 440 220 110 55 166 83 250 125 376 188 94 47 142 71 214 107 322 161 484 242 121 364 182 91 274 137 412 206 103 310 155 466 233 700 350 175 526 263 790 395 1186 593 1780 890 445 1336 668 334 167 502 251 754 377 1132 566 283 850 425 1276 638 319 958 479 1438 719 2158 1079 3238 1619 4858 2429 7288 3644 1822 911 2734 1367 4102 2051 6154 3077 9232 4616 2308 1154 577 1732 866 433 1300 650 325 976 488 244 122 61 184 92 46 23 70 35 106 53 160 80 40 20 10 5 16 8 4 2 1
Child Complete (41838 - 0x0000)
$
I'm having a slight problem with interpositioning the sleep function at run time. I'm currently trying to test library interpositioning at runtime using a simple source code, "sleepdemo.c" and "wakeup.c".
The code(wakeup.c) I have wrote is as following:
1 #ifdef RUNTIME
2 #define _GNU_SOURCE
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <dlfcn.h>
6 #include <stdlib.h>
7
8 /* sleep wrapper function*/
9 unsigned int wakeup(unsigned int secs)
10 {
11 unsigned int (*wakeupp)(unsigned int secs);
12 char *error;
13
14 wakeupp = dlsym(RTLD_NEXT, "sleep"); //Get address of sleep
15 if((error = dlerror()) != NULL){
16 fputs(error, stderr);
17 exit(1);
18 }
19
20 unsigned int elapsed = sleep(secs);
21 printf("Woke up at %d secs.\n", secs - elapsed+1);
22 return elapsed;
23 }
24
25 #endif
And this is the code I'm trying to interpose:
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4
5 int main()
6 {
7 int secs = 1;
8
9 printf("This is sleep demo program.\n");
10 sleep(secs);
11 return 0;
12 }
And I have given following instructions to my gcc to create an shared library:
gcc -DRUNTIME -shared -fpic -o mysleep.so wakeup.c -ldl
LD_PRELOAD="./mysleep.so" ./wakeup
Hardware:
Darwin Kernel Version 13.2.0: Thu Apr 17 23:03:13 PDT 2014; root:xnu-2422.100.13~1/RELEASE_X86_64 x86_64
atomics.hpp
1 #ifndef ATOMIC_UTILS_H
2 #define ATOMIC_UTILS_H
3
4 #include
5
6 #define BARRIER() __asm__ volatile ( "": : :"memory" )
7
8 #define CPU_RELAX() __asm__ volatile( "pause\n\t": : :"memory" )
9
10 #define STORE_FENCE() __asm__ volatile("mfence" ::: "memory");
11
12 class AtomicUtils
13 {
14 public:
15
16 /**
17 * check if the value at addr is equal to oldval, if so replace it with newva l
18 * and return the oldval
19 */
20 inline static size_t compareAndExchange( volatile size_t* addr, size_t oldval , size_t newval )
21 {
22 size_t ret;
23 __asm__ volatile( "lock cmpxchgq %2, %1\n\t"
24 :"=a"(ret), "+m"(*addr)
25 : "r"(newval), "0"(oldval)
26 : "memory" );
27 return ret;
28 }
29
30 /**
31 * Atomically stores x into addr and returns the previous
32 * stored in addr
33 */
34 inline static size_t loadAndStore( size_t x, volatile size_t* addr )
36 {
37 size_t ret;
38 __asm__ volatile( "lock xchgq %1, %0\n\t"
39 : "+m"(*addr), "=r"(ret)
40 : "1"(x) );
41 return ret;
42 }
43
44 };
45
46 #endif
mcs.hpp
1 #ifndef MCS_LOCK_H
2 #define MCS_LOCK_H
3
4 #include "atomics.hpp"
5 #include
6
7 class MCSLock
8 {
9 struct mcs_lock_t
10 {
11 mcs_lock_t():next(0), locked(false){}
12 struct mcs_lock_t* next;
13 bool locked;
14 };
15
16 public:
17 typedef struct mcs_lock_t mcs_lock;
18
19 private:
20 mcs_lock** tail;
21 static boost::thread_specific_ptr tls_node;
22
23 public:
24 MCSLock( mcs_lock** lock_tail ):tail( lock_tail )
25 {
26 if( tls_node.get() == 0 )
27 tls_node.reset( new mcs_lock() );
28 }
29
30 void lock()
31 {
32 mcs_lock* thread_node = tls_node.get();
33 thread_node->next = 0;
34 thread_node->locked = true;
35
36 volatile mcs_lock* pred = reinterpret_cast(
37 AtomicUtils::loadAndStore(
38 reinterpret_cast( thread_node ),
39 reinterpret_cast( tail )
40 )
41 );
42 if( pred != 0 )
43 {
44 pred->next = *tail;
45
46 STORE_FENCE();
47 //BARRIER(); // Required to prevent re ordering between prev->next = tail and thread_node->locked. ( WR harzard )
48
49 // Spin on a local variable. Someone unlock me plz !!
50 while( thread_node->locked )
51 CPU_RELAX();
52
53 }
54 }
55
56 void unlock()
57 {
58 mcs_lock* thread_node = tls_node.get();
59 if( thread_node->next == 0 )
60 {
61 // If false, then we a new thread has request for lock. Now release t he lock for the new thread
62 if(
63 AtomicUtils::compareAndExchange(
64 reinterpret_cast( tail ),
65 reinterpret_cast( thread_node ),
66 0
67 ) == reinterpret_cast( thread_node ) 68 )
69 {
70 return;
71 }
72
73 while( thread_node->next == 0 )
74 CPU_RELAX();
75 }
76
77 thread_node->next->locked = false;
78 }
79 };
80
81 boost::thread_specific_ptr MCSLock::tls_node;
82 #endif
mcs_test.cpp
1 #include "mcs.hpp"
2 #include <iostream>
3 #include <pthread.h>
4 #include <vector>
5 #define NUM_THREADS 16
6 #define NUM_ITERATIONS 100
7
8 std::vector<int> elements;
9 MCSLock::mcs_lock *tail = 0;
10
11 void* thread_run( void* data )
12 {
13 MCSLock lock( &tail );
14 for( int i = 0; i < NUM_ITERATIONS; ++i )
15 {
16 lock.lock();
17 elements.push_back( i );
18 lock.unlock();
19 }
20
21 return 0;
22 }
23
24 int main()
25 {
26 pthread_t threads[ NUM_THREADS ];
27 elements.reserve( NUM_THREADS * NUM_ITERATIONS );
28
29 {
30 for( int i = 0; i < NUM_THREADS; ++i )
31 pthread_create( &threads[i], NULL, thread_run, NULL );
32
33 for( int i = 0; i < NUM_THREADS; ++i )
34 pthread_join( threads[i], NULL );
35
36 std::cout <<"\nExiting main thread: " << std::endl;
37 }
38 }
The above code is compiled using clang
Problem:
I see that 1 or 2 threads are stuck in lock() in line 50. Except the main threads, the threads which are stuck in lock() there are no other threads alive. This means that when the other threads invoke unlock() they somehow don't set the locked = false for other variables and exit.
Any pointers on debugging this please ?
Stuck on this for many hours and no clues.
Doesn't clang have builtins for these inline-asm blocks (like gcc's __sync_val_compare_and_swap)? Why re-invent the wheel?
Second, I'd really think about adding the memory clobber to loadAndStore. You need to make sure that any writes the compiler is holding in registers gets flushed to memory before doing the xchgq. Similarly it will prevent gcc from optimizing memory reads to before the xchgq. Either would be bad.
Third, I'd examine the asm output for your while loops (thread_node->locked and thread_node->next). Since these variables are not volatile, gcc may optimize this to only perform the read once.
These may not solve your problem, but that's where I'd start.
I am learning to program in MPI and I came across this question. Lets say I have a .txt file with 100,000 rows/lines, how do I chunk them for processing by 4 processors? i.e. I want to let processor 0 take care of the processing for lines 0-25000, processor 1 to take care of 25001-50000 and so on. I did some searching and did came across MPI_File_seek but I am not sure can it work on .txt and supports fscanf afterwards.
Text isn't a great format for parallel processing exactly because you don't know ahead of time where (say) line 25001 begins. So these sorts of problems are often dealt with ahead of time through some preprocessing step, either building an index or partitioning the file into the appropriate number of chunks for each process to read.
If you really want to do it through MPI, I'd suggest using MPI-IO to read in overlapping chunks of the text file onto the various processors, where the overlap is much longer than you expect your longest line to be, and then have each processor agree on where to start; eg, you could say that the first (or last) new line in the overlap region shared by processes N and N+1 is where process N leaves off and N+1 starts.
To follow this up with some code,
#include <stdio.h>
#include <mpi.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
void parprocess(MPI_File *in, MPI_File *out, const int rank, const int size, const int overlap) {
MPI_Offset globalstart;
int mysize;
char *chunk;
/* read in relevant chunk of file into "chunk",
* which starts at location in the file globalstart
* and has size mysize
*/
{
MPI_Offset globalend;
MPI_Offset filesize;
/* figure out who reads what */
MPI_File_get_size(*in, &filesize);
filesize--; /* get rid of text file eof */
mysize = filesize/size;
globalstart = rank * mysize;
globalend = globalstart + mysize - 1;
if (rank == size-1) globalend = filesize-1;
/* add overlap to the end of everyone's chunk except last proc... */
if (rank != size-1)
globalend += overlap;
mysize = globalend - globalstart + 1;
/* allocate memory */
chunk = malloc( (mysize + 1)*sizeof(char));
/* everyone reads in their part */
MPI_File_read_at_all(*in, globalstart, chunk, mysize, MPI_CHAR, MPI_STATUS_IGNORE);
chunk[mysize] = '\0';
}
/*
* everyone calculate what their start and end *really* are by going
* from the first newline after start to the first newline after the
* overlap region starts (eg, after end - overlap + 1)
*/
int locstart=0, locend=mysize-1;
if (rank != 0) {
while(chunk[locstart] != '\n') locstart++;
locstart++;
}
if (rank != size-1) {
locend-=overlap;
while(chunk[locend] != '\n') locend++;
}
mysize = locend-locstart+1;
/* "Process" our chunk by replacing non-space characters with '1' for
* rank 1, '2' for rank 2, etc...
*/
for (int i=locstart; i<=locend; i++) {
char c = chunk[i];
chunk[i] = ( isspace(c) ? c : '1' + (char)rank );
}
/* output the processed file */
MPI_File_write_at_all(*out, (MPI_Offset)(globalstart+(MPI_Offset)locstart), &(chunk[locstart]), mysize, MPI_CHAR, MPI_STATUS_IGNORE);
return;
}
int main(int argc, char **argv) {
MPI_File in, out;
int rank, size;
int ierr;
const int overlap = 100;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (argc != 3) {
if (rank == 0) fprintf(stderr, "Usage: %s infilename outfilename\n", argv[0]);
MPI_Finalize();
exit(1);
}
ierr = MPI_File_open(MPI_COMM_WORLD, argv[1], MPI_MODE_RDONLY, MPI_INFO_NULL, &in);
if (ierr) {
if (rank == 0) fprintf(stderr, "%s: Couldn't open file %s\n", argv[0], argv[1]);
MPI_Finalize();
exit(2);
}
ierr = MPI_File_open(MPI_COMM_WORLD, argv[2], MPI_MODE_CREATE|MPI_MODE_WRONLY, MPI_INFO_NULL, &out);
if (ierr) {
if (rank == 0) fprintf(stderr, "%s: Couldn't open output file %s\n", argv[0], argv[2]);
MPI_Finalize();
exit(3);
}
parprocess(&in, &out, rank, size, overlap);
MPI_File_close(&in);
MPI_File_close(&out);
MPI_Finalize();
return 0;
}
Running this on a narrow version of the text of the question, we get
$ mpirun -n 3 ./textio foo.in foo.out
$ paste foo.in foo.out
Hi guys I am learning to 11 1111 1 11 11111111 11
program in MPI and I came 1111111 11 111 111 1 1111
across this question. Lets 111111 1111 111111111 1111
say I have a .txt file with 111 1 1111 1 1111 1111 1111
100,000 rows/lines, how do 1111111 11111111111 111 11
I chunk them for processing 1 11111 1111 111 1111111111
by 4 processors? i.e. I want 22 2 22222222222 2222 2 2222
to let processor 0 take care 22 222 222222222 2 2222 2222
of the processing for lines 22 222 2222222222 222 22222
0-25000, processor 1 to take 22222222 222222222 2 22 2222
care of 25001-50000 and so 2222 22 22222222222 222 22
on. I did some searching and 333 3 333 3333 333333333 333
did came across MPI_File_seek 333 3333 333333 3333333333333
but I am not sure can it work 333 3 33 333 3333 333 33 3333
on .txt and supports fscanf 33 3333 333 33333333 333333
afterwards. 33333333333