I am trying to produce a race condition (assuming that there exists a critical section in the csfunc) with the following sample code:
#include <stdio.h>
#include <pthread.h>
int cs = 0;
void* csfunc(void* arg){
for (int i = 0; i < 1000000; i++){
cs++;
cs--;
if (cs!=0){
printf("cs: %d\n", cs);
}
}
}
int main(){
for (int i = 0; i < 100; i++){
pthread_t t;
pthread_create(&t,NULL,csfunc,NULL);
pthread_join(t,NULL);
}
return 0;
}
I assume that 100 threads with 1000000 iterations are enough to do a lot of race conditions. Nonetheless, my code is not producing even one single printing of the value of cs. Any ideas? Or am I missing something?
PS> Please note that I am using the gcc compiler with the following command
gcc cs.c -lpthread -o cs
When you do join, it waits until that thread is finished then continues the loop. So you should put thread handles in an array and wait for all of them.
pthread_t handles[100];
for (int i = 0; i < 100; i++){
pthread_create(&handles[i],NULL,csfunc,NULL);
}
for (int i = 0; i < 100; ++i)
pthread_join(handes[i],NULL);
Related
I'm working with Visual Studio C.
I found that the programs report errors in a strange way when I write outside the range of an allocated vector.
This first program:
#include <stdio.h>
#include <stdlib.h>
int main() {
int* qwe = (int*)calloc(100, sizeof(int));
for (int j = 0; j < 210; j++) qwe[j] = 1; // Wrong range!
printf("Hi!");
for (int k=0;k<1000;k++) \\ just to spend time!
for (int j = 0; j < 100000; j++)
sin(cos(j));
}
simply stops before "Hi!". This one:
#include <stdio.h>
#include <stdlib.h>
int main() {
int* qwe = (int*)calloc(100, sizeof(int));
int* asd = (int*)calloc(100, sizeof(int));
for (int j = 0; j < 210; j++) qwe[j] = 1;
printf("Hi!");
for (int k=0;k<1000;k++)
for (int j = 0; j < 100000; j++)
sin(cos(j));
}
ends without reporting any problem, although the difference is just that I allocated an extra array. And finally this:
#include <stdio.h>
#include <stdlib.h>
int main() {
int* qwe = (int*)calloc(100, sizeof(int));
int* asd = (int*)calloc(100, sizeof(int));
for (int j = 0; j < 210; j++) qwe[j] = 1;
printf("Hi!");
for (int k=0;k<1000;k++)
for (int j = 0; j < 100000; j++)
sin(cos(j));
free(qwe);
free(asd);
}
runs but, at the end (after the useless cycles), it gives me this message:
Of course, I know how to avoid the problem: just, pay attention to the index range. But my question is: what is exactly the meaning of the error message? What is the "normal block"? Why "after" and not "before"? What is exactly the displayed address? Why the message is issued only at the "free" command and not when the "heap corruption" takes place?
_NORMAL_BLOCK tells you what kind of allocation it was, there are also _CRT_BLOCK (internal to the library), _CLIENT_BLOCK (also allocated by user code but with some special handling available), and _FREE_BLOCK.
It's "after" and not "before" due to the order that corruption is check for. Since overruns are more likely than under that is checked for first.
The reason it waits until free is called is simply because it only checks during allocation and de-allocation calls. It would make programs run enormously slower if there were a system in place that checked every write to make sure it is in bounds.
This question already has answers here:
initializing a static variable in header
(4 answers)
Closed 5 years ago.
I'm trying to compare performance of methods about adding two matrix.
one method is just to add.
the other method is to use threads.
but I have a trouble about segmentation error when a thread access a static variable!
Here is my code.
main.c
#include "matrixProcessor.h"
void main()
{
time_t s0, e0;
int i;
int status;
inputVec1 = (int*)malloc(sizeof(int)*(SIZE*SIZE));
inputVec2 = (int*)malloc(sizeof(int)*(SIZE*SIZE));
outputVec = (int*)malloc(sizeof(int)*(SIZE*SIZE));
srand(time(NULL));
initializeVector(inputVec1);
initializeVector(inputVec2);
//printf("=== INPUT VECTOR 1 ===\n");
//printVector(inputVec1);
//printf("=== INPUT VECTOR 1===\n");
//printVector(inputVec2);
//s0 = clock();
//addVec(inputVec1, inputVec2, outputVec);
//e0 = clock();
//printf("Basic Method Time : %f (s)\n",(double)(e0-s0)/CLOCKS_PER_SEC);
s0 = clock();
for(i = 0; i < NUM_THREAD; i++)
{
printf("%d-Thread Call\n",i);
pthread_create(&tid[i], NULL, &addProc, (void*)&i);
sleep(1);
}
e0 = clock();
printf("=== OUTPUT VECTOR===\n");
printVector(outputVec);
printf("Thread Method Time : %f (s)\n",(double)(e0-s0)/CLOCKS_PER_SEC);
free(inputVec1);
free(inputVec2);
free(outputVec);
}
matrixProcessor.c
#include "matrixProcessor.h"
void initializeVector(int* matPtr)
{
int i = 0;
for(i = 0; i < SIZE*SIZE ; i++)
{
matPtr[i] = rand()%100;
}
}
void addVec(int* inputVec1, int* inputVec2, int* outputVec)
{
int i = 0;
for(i = 0; i < SIZE * SIZE; i++)
{
outputVec[i] = inputVec1[i] + inputVec2[i];
}
}
void* addProc(void *p)
{
int* idx = (int*)p;
int count = (SIZE * SIZE) / NUM_THREAD;
int i;
printf("idx value : %d\n",*idx);
printf("Test : %d ", inputVec1[0]);
for(i = (*idx) * count ; i < (*idx)*count + count; i++)
{
outputVec[i] = inputVec1[i] + inputVec2[i];
}
return NULL;
}
void printVector(int* vec)
{
int i = 0;
int j = 0;
for(i = 0; i < SIZE ; i++)
{
for(j = 0; j < SIZE; j++)
{
printf("%d\t", vec[SIZE * i + j]);
}
printf("\n");
}
}
matrixProcessor.h
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#define SIZE 10
#define NUM_THREAD 10
pthread_t tid[NUM_THREAD];
static int* inputVec1;
static int* inputVec2;
static int* outputVec;
void initializeVector(int* matPtr);
void printVector(int* vec);
void addVec(int* inputVec1, int* inputVec2, int* outputVec);
void* addProc(void *p);
when compiling, i use -static - lpthread options.
I'm sure that accessing static variable cause segmentation error,
because this program prints some messages before reaching a code line which access static variable.
Here is result.
0-Thread Call
idx value : 0
Segmentation Error! ./main
Please someone help me..!
There are multiple problems in your code. The two that jump right out to me are listed below.
First, this one:
pthread_create(&tid[i], NULL, &addProc, (void*)&i);
What's the value of i when the child thread accesses it? It can be anything, because it changes as the main thread spawns more threads and continues to run.
Second, what do you think these free() statements do when they're executed while the child threads are still running:
free(inputVec1);
free(inputVec2);
free(outputVec);
When your code makes those calls, the child threads are still running since you don't call pthread_join() to make sure they've all completed.
You likely get the segmentation violation because your threads are accessing free()'d memory.
I have a huge multi-threaded code base. There are 100 threads. 99 threads have a function do_thread_operations associated with each of them. 100th thread has an operation monitor_99threads associated with it.
do_thread_operations have infinite loop, so they never stop. monitor_99threads keeps track of time. One minute after it was started, it has to close all 99 threads and return to the main thread.
Following is my code.
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
int *to_close_thread;
void * do_thread_operations(void * thread_data){
int i = *(int *)thread_data;
while (1){
//do something
if (to_close_thread[i]) break;
}
}
void * monitor_99threads(void * data){
int i = 0;
while(1){
i++;
if(i > 60){
for (int i = 0; i < 99; ++i){
printf("Closing %d", i);
to_close_thread[i] = 1;
}
}
}
}
int main(){
to_close_thread = (int *)malloc(99 * sizeof(int));
memset(to_close_thread, 0, 99*sizeof(int));
pthread_t threads[100];
for (int i = 0; i < 99; ++i){
int j = i;
pthread_create(&threads[i], NULL, do_thread_operations, (void *)&j);
}
pthread_create(&threads[99], NULL, monitor_99threads, NULL);
for (int i = 0; i < 100; ++i){
pthread_join(threads[i], NULL);
}
}
Problem is that although closing prints, the threads do not break out of their loops.
In addition to the problems described by #P.P., there appears to be a synchronization problem with the referent of to_close_thread. Since the elements are not _Atomic and they are accessed without protection of a mutex, semaphore, or other synchronization object, the do_thread_operations() threads may not ever see any writes performed by control_99threads().
Note also, by the way, that it's a bit silly to pass a pointer to an offset from the base of to_close_thread as the thread argument, when you could instead just pass a pointer directly to the appropriate element. Then you don't need any kind of auxiliary variable:
for (int i = 0; i < 99; ++i){
pthread_create(&threads[i], NULL, do_thread_operations,
(void *) (to_close_thread + i));
}
The do_thread_operations can just cast it back to an int * and dereference it directly (under protection of a mutex or other appropriate synchronization object).
Here,
for (int i = 0; i < 99; ++i){
int j = i;
pthread_create(&threads[i], NULL, do_thread_operations, (void *)&j);
}
You are passing the address of j, which has block scope and has auto storage duration. You should something like:
int arr[100] = {0}; /* adjust the number or allocate using malloc as per needs */
for (int i = 0; i < 99; ++i){
arr[i] = i;
pthread_create(&threads[i], NULL, do_thread_operations, &arr[i]);
}
Another problem is your monitor thread doesn't break after sending closing message. As it is, it's running in an infinite loop. You probably need a break; statement when (whatever) condition is met.
Need help how to prevent the deadlock for the code in blow i have written. or any suggestion i need to fix the code in order to get rid of deadlock?
also when i run in Linux i got a Segmentation fault (core dumped).
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <pthread.h>
#include <semaphore.h>
int cnt;
int *bites;
int *old_bites;
sem_t *sticks;
void *roger(void *arg) {
int rog = *(int*)arg;
for(;;) {
sem_wait(&(sticks[rog])); // left
sem_wait(&(sticks[(rog + 1) % cnt])); // right
bites[rog]++;
sem_post(&(sticks[(rog + 1) % cnt])); // right
sem_post(&(sticks[rog])); // left
}
pthread_exit(NULL);
return NULL;
}
int main(int argc, char *argv[]) {
int i;
pthread_t *rogers;
int *pos;
cnt = (int)strtol(argv[1], NULL, 10);
rogers = (pthread_t *)calloc(cnt, sizeof(pthread_t));
pos = (int *)malloc(cnt * sizeof(int));
bites = (int *)calloc(cnt, sizeof(int));
old_bites = (int *)calloc(cnt, sizeof(int));
sticks = (sem_t *)calloc(cnt, sizeof(sem_t));
for(i = 0; i < cnt; i++) {
sem_init(&(sticks[i]), 0, 1);
}
for(i = 0; i < cnt; i++) {
pos[i] = i;
pthread_create(&(rogers[i]), NULL, roger, (void *)&pos[i]);
}
for(;;) {
bool dead = true;
usleep(50000);
for(i = 0; i < cnt; i++) {
if(bites[i] != old_bites[i]) {
dead = false;
}
}
if(dead) {
exit(EXIT_SUCCESS);
}
for(i = 0; i < cnt; i++) {
printf("%8X", bites[i]);
}
printf("\n");
for(i = 0; i < cnt; i++) {
old_bites[i] = bites[i];
}
}
for(i = 0; i < cnt; i++) {
pthread_join(rogers[i], NULL);
}
for(i = 0; i < cnt; i++) {
sem_destroy(&(sticks[i]));
}
exit(EXIT_SUCCESS);
}
yes I would expect this to deadlock. I don't know what you're using for cnt, but let's pretend it's 1. In this case, only 1 thread will get created. This thread will sem_wait(&(sticks[0]));. Then in the very next line it will sem_wait(&(sticks[(0+1) % 1 == 0]));. Since the initial value of your semaphores are 1, you can't wait on the same semaphore twice without a sem_post first. Thus, this thread will wait forever for a sem_post that it can't reach because it's sem_waiting.
Now consider the case where cnt > 1 (let's just say cnt == 2 to make it simpler). This will spawn thread0 and thread1 with 0 and 1 passed as arguments to their functions. This situation could happen:
Thread0 executes sem_wait(&(sticks[0]));
Context switch: thread1 executes sem_wait(&(sticks[1]));
thread1 executes sem_wait(&(sticks[(1+1) % 2 == 0])); // this blocks because thread0 has already sem_wait'ed this semaphore to 0
Context switch: thread0 executes sem_wait(&(sticks[(0+1) % 2 == 1])); // this blocks because thread1 has already sem_wait'ed this semaphore to 0
Now you have each thread waiting for a sem_post from the other before you can continue ==> deadlock. I would expect this scenario to scale for increasing values of cnt, although the situations that would lead to deadlocks would become more complex.
Why are you using 2 semaphores to protect a single resource? This theory sounds wrong to me. You lose your atomicity with that approach (correct me if I'm wrong obviously).
Also, you have a race condition with your bites array. The main thread isn't observing synchronization before it reads from it. This may be related to the seg fault.
I was trying to build a system (in Linux) with a simulated time execution, coordinating threads with semaphores, the idea was to make them all work cycles of one second, to have a accurate simulation the threads must wait for every other thread to end its execution, on the current simulated second.
I had a really annoying memory leak, because the main thread finished the work without joining the other threads (newbie mistake), so to solve it I added pthread_join() instructions for every thread, supposing they were finishing its work, since every thread execution was inside a while loop with a global condition to check, which was changed by the main thread before finishing. Sadly even with that, now, most of the executions of the program, it gets frozen waiting for the thread to finish.
I need to find a way to end every thread execution, even ignoring its full work, but making sure the join is made (and so the memory is freed).
Now I post a compilable code with the error, you can compile it with gcc -o sample -pthread sample.c -lm
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <pthread.h>
#include <semaphore.h>
#include <math.h>
#define SIZE 100
#define READY 12345
#define END 99
#define TIME 3600
int *advicer;
int *td;
pthread_t *phones;
sem_t *counter;
int ready;
int end;
void cycle(int cycles){
int i,j,k;
for(i = 0; i < cycles; i++){
k = 1;
while(k){
k = 0;
for(j = 0; j < SIZE; j++){
if(advicer[j] == 0){
k = 1;
break;
}
}
}
for(j = 0; j < SIZE; j++){
advicer[j] = 0;
sem_post(&counter[j]);
}
}
}
void *do_something(void *td){
int t;
t = *((int *) td);
while(end != END){
if(end == END)
break;
t += t;
advicer[t] = 1;
sem_wait(&counter[t]);
}
pthread_exit(NULL);
}
void all_free(){
int i,j;
end = END;
printf("reach %d\n",end);
for(i = 0; i < SIZE; i++)
sem_post(&counter[i]);
printf("reach2\n");
for(i = 0; i < SIZE; i++){
pthread_join(phones[i],NULL);
}
free(phones);
printf("reach3\n");
for(i = 0; i < SIZE; i++)
sem_destroy(&counter[i]);
free(counter);
free(td);
free(advicer);
}
void main(){
int i,my_count;
counter = (sem_t *)malloc(sizeof(sem_t)*SIZE);
advicer = (int *)malloc(sizeof(int)*SIZE);
td = (int *)malloc(sizeof(int)*SIZE);
phones = (pthread_t *)malloc(sizeof(pthread_t)*SIZE);
for(i = 0; i < SIZE; i++){
sem_init(&counter[i], 0, 0);
advicer[i] = 0;
}
ready = READY;
my_count = 0;
end = 0;
for(i = 0; i < SIZE; i++){
td[i] = i;
pthread_create(&(phones[i]), NULL, do_something, (void *)(&td[i]));
}
printf("starting simulation\n");
while(my_count < TIME){
cycle(60);
printf("hello\n");
my_count += 60;
}
printf("simulation ended\n");
all_free();
}
The following section could lead to the lock:
for(i = 0; i < m->pp; i++)
sem_post(&counter[i]);
for(i = 0; i < m->pp; i++){
if(m->ppl[i] != NULL){
phone_free(m->ppl[i]);
}
...
}
You call sem_post() for one thread only (which unlocks it) then call pthread_join() (via phone_free()) for all threads, which would block for all but the one you called sem_post() for, as the others do not terminate, because stuck in sem_wait().
Although you called sem_post() during main execution (cycle()) the value might have been fetched by the thread prior to your call to the end-execution code (map_free()) pthread_join() (via phone_free()).
To cancel a thread you could use pthread_cancel().
To avoid the memory leak when having left a thread and not calling pthread_join() on it, you could detach the thread using pthread_detach(). The OS then frees all of the thread's resouce when the thread terminates.