edit string in multi thread - c++

I am newer for c++, and I know in c++0x multithreading support is poor.
But now I have to edit a string val in multi thread, I use thread_mutex to protect the val. The problem is the program always core dump when runing.
Although after re-design I find a better solution but I can't figure out why it core. So could some one told me about what happend?
The code is like below
using namespace std;
const static int kThreadSize = 48;
map<string, string> gMap;
string gStr = "";
void * func(void * data)
{
while(true)
{
printf("%s\n", gStr.c_str());
pthread_mutex_t m;
pthread_mutex_init(&m, NULL);
pthread_mutex_lock(&m);
gStr = gStr + "a";//core in this line
printf("%x\n", &gStr);//print the address
pthread_mutex_unlock(&m);
pthread_mutex_destroy(&m);
printf("%s\n", gStr.c_str());
}
}
int main()
{
pthread_t threads[kThreadSize];
for(int i = 0; i < kThreadSize; i ++)
{
pthread_create(&threads[i], NULL, &func, &gMap);
}
for(int i = 0; i < kThreadSize; i ++)
{
pthread_join(threads[i], NULL);
}
return 0;
}
EDIT:
By using the global mutex will solve the problem pointed by Mike.Here I don't paste the new source code.
My new question is I also can't understand why it will core when edit a string in multithreading. Because of COW or reference count?

As i can see there is a problem with yours Mutex, because it is create into the method func() and it make that each thread invocation of func()create a new mutex, it is happened by each threat that invokes this method.
As MikeB says, i sugest you review the thread theory but, meanwhile, try to use a unique mutex to synchronize the access to gMap, as the example shows:
using namespace std;
const static int kThreadSize = 48;
map<string, string> gMap;
string gStr = "";
pthread_mutex_t m;
void * func(void * data)
{
while(true)
{
printf("%s\n", gStr.c_str());
pthread_mutex_lock(&m);
gStr = gStr + "a";//core in this line
printf("%x\n", &gStr);//print the address
pthread_mutex_unlock(&m);
printf("%s\n", gStr.c_str());
}
}
int main()
{
pthread_mutex_init(&m, NULL);
pthread_t threads[kThreadSize];
for(int i = 0; i < kThreadSize; i ++)
{
pthread_create(&threads[i], NULL, &func, &gMap);
}
for(int i = 0; i < kThreadSize; i ++)
{
pthread_join(threads[i], NULL);
}
return 0;
}

Related

Locking on Multithreaded openssl is not working

I have a server. When I try to run the server with multi threading, it crashes. After that I found, I have to manually provide locking in openssl to avoid crashing. After providing static lock also, server gets crashing. I will attach my code here. can anyone say what's wrong in it?
Code:
BIO *bio_err = NULL;
static pthread_mutex_t *lock_cs;
static long *lock_count;
void pthreads_locking_callback(int mode, int type, const char *file,int line)
{
if (mode & CRYPTO_LOCK) {
pthread_mutex_lock(&(lock_cs[type]));
lock_count[type]++;
} else {
pthread_mutex_unlock(&(lock_cs[type]));
}
}
void pthreads_thread_id(CRYPTO_THREADID *tid)
{
unsigned long data = (unsigned long)pthread_self();
CRYPTO_THREADID_set_numeric(tid, (unsigned long)data);
}
void thread_setup(void)
{
int i;
lock_cs = (pthread_mutex_t*)OPENSSL_malloc(CRYPTO_num_locks()* sizeof(pthread_mutex_t));
lock_count = (long int *)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
for (i = 0; i < CRYPTO_num_locks(); i++) {
lock_count[i] = 0;
pthread_mutex_init(&(lock_cs[i]), NULL);
}
CRYPTO_THREADID_set_callback(pthreads_thread_id);
CRYPTO_set_locking_callback(pthreads_locking_callback);
}
void thread_cleanup(void)
{
int i;
CRYPTO_set_locking_callback(NULL);
BIO_printf(bio_err, "cleanup\n");
for (i = 0; i < CRYPTO_num_locks(); i++) {
pthread_mutex_destroy(&(lock_cs[i]));
BIO_printf(bio_err, "%8ld:%s\n", lock_count[i], CRYPTO_get_lock_name(i));
}
OPENSSL_free(lock_cs);
OPENSSL_free(lock_count);
BIO_printf(bio_err, "done cleanup\n");
}

Call join child pthread in main function

I have the test code:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
pthread_t th_worker, th_worker2;
void * worker2(void *data) {
for(int i = 0; i< 1000000; i++){
printf("thread for worker2----%d\n", i);
usleep(500);
}
}
void * worker(void *data){
pthread_create(&th_worker2, NULL, worker2, data);
for(int i = 0; i< 100; i++){
printf("thread for worker-----%d\n", i);
usleep(500);
}
}
void join(pthread_t _th){
pthread_join(_th, NULL);
}
In main() function, If I call join(the_worker2):
int main() {
char* str = "hello thread";
pthread_create(&th_worker, NULL, worker, (void*) str);
/* problem in here */
join(th_worker2);
return 1;
}
--> Segment Fault error
Else, i call:
join(the_worker);
join(th_worker2);
---> OK
Why have segment fault error in above case?
Thanks for help !!!
If you posted all your code, you have a race condition.
main is synchronized with the start of worker but not worker2.
That is, main is trying to join th_worker2 before worker has had a chance to invoke pthread_create and set up th_worker2 with a valid [non-null] value.
So, th_worker2 will be invalid until the second pthread_create completes, but that's already too late for main. It has already fetched th_worker2, which has a NULL value and main will segfault.
When you add the join for th_worker, it works because it guarantees synchronization and no race condition.
To achieve this guarantee without the join, have main do:
int
main()
{
char *str = "hello thread";
pthread_create(&th_worker, NULL, worker, (void *) str);
// give worker enough time to properly start worker2
while (! th_worker2)
usleep(100);
/* problem in here */
join(th_worker2);
return 1;
}
An even better way to do this is to add an extra variable. With this, the first loop is not needed [but I've left it in]:
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
int worker_running;
pthread_t th_worker;
int worker2_running;
pthread_t th_worker2;
void *
worker2(void *data)
{
// tell main we're fully functional
worker2_running = 1;
for (int i = 0; i < 1000000; i++) {
printf("thread for worker2----%d\n", i);
usleep(500);
}
return NULL;
}
void *
worker(void *data)
{
// tell main we're fully functional
worker_running = 1;
pthread_create(&th_worker2, NULL, worker2, data);
for (int i = 0; i < 100; i++) {
printf("thread for worker-----%d\n", i);
usleep(500);
}
return NULL;
}
void
join(pthread_t _th)
{
pthread_join(_th, NULL);
}
int
main()
{
char *str = "hello thread";
pthread_create(&th_worker, NULL, worker, (void *) str);
// give worker enough time to properly start worker2
// NOTE: this not necessarily needed as loop below is better
while (! th_worker2)
usleep(100);
// give worker2 enough time to completely start
while (! worker2_running)
usleep(100);
/* problem in here (not anymore!) */
join(th_worker2);
return 1;
}

C++ Wait all threads to finish

#include <stdio.h>
#include <process.h>
#include <wtypes.h>
typedef unsigned int (__stdcall * THREAD_FUN_TYPE)(void *);
int ThreadIp(void* param)
{
while(true)
{
printf("I'm runing!\n");
}
return 0;
}
int main()
{
int iThreadNum=100;
HANDLE* phThreads = new HANDLE[iThreadNum];
for (int i=0;i<iThreadNum;++i)
{
phThreads[i]=(HANDLE*)_beginthreadex(NULL, 0, (THREAD_FUN_TYPE)ThreadIp,NULL, NULL, NULL);
}
int nIndex = ::WaitForMultipleObjects(iThreadNum,phThreads,1,INFINITE);
printf("End!\n");
return 0;
}
I want the program will halt at WaitForMultipleObjects until all thread are end(Not until all thread are created successfully).But the program will not halt at WaitForMultipleObjects,while all threads are still running. So I try to use SetEvent,but still the same problem:
int iThreadNum=100;
HANDLE* phThreads = new HANDLE[iThreadNum];
for (int i=0;i<iThreadNum;++i)
{
phThreads[i]=CreateEvent(NULL, FALSE, FALSE,NULL);
ResetEvent(phThreads[i]);
}
int nIndex = ::WaitForMultipleObjects(iThreadNum,phThreads,1,INFINITE);
You should wait on the thread handles, not the unrelated events:
Try something like this:
int iThreadNum=100;
HANDLE* phThreads = new HANDLE[iThreadNum];
for (int i=0;i<iThreadNum;++i)
{
m_iCurThreadNum=i;
phThreads[i] = _beginthreadex(...);
}
int nIndex = ::WaitForMultipleObjects(iThreadNum,phThreads,1,INFINITE);
Does it work if you have fewer threads? The manual says you need to do extra work if you have more than MAXIMUM_WAIT_OBJECTS, specifically
nCount [in] The number of object handles in the array pointed to by
lpHandles. The maximum number of object handles is
MAXIMUM_WAIT_OBJECTS. This parameter cannot be zero.
See here for a discussion.
It might be worth checking what the wait function has returned too.
I would allocate a struct before calling _beginthreadex and pass the pointer to the struct through the threads parameter and have the struct contain a bool which is set by the thread when it's done.
struct ThreadStruct{
bool Done;
char* ParamData;
int ParamDataSize;
};
int ThreadIp(void* param)
{
ThreadStruct* ts = (ThreadStruct*)param;
while(true)
{
printf("I'm runing!\n");
}
ts->Done = true;
return 0;
}
int main()
{
int iThreadNum=100;
HANDLE* phThreads = new HANDLE[iThreadNum];
ThreadStruct* structs = new ThreadStruct[iThreadNum];
for (int i=0;i<iThreadNum;++i)
{
ZeroMemory(structs[i], sizeof(ThreadStruct));
phThreads[i]=(HANDLE*)_beginthreadex(NULL, 0, (THREAD_FUN_TYPE)ThreadIp, structs[i], NULL, NULL);
ResetEvent(phThreads[i]);
}
for(unsigned int i=0; i<iThreadNum;){
if(!structs[i]->Done) i=0;
else i++;
}
printf("End!\n");
return 0;
}

C++ Using semaphores instead of busy waiting

I am attempting to learn about semaphores and multi-threading. The example I am working with creates 1 to t threads with each thread pointing to the next and the last thread pointing to the first thread. This program allows each thread to sequentially take a turn until all threads have taken n turns. That is when the program ends. The only problem is in the tFunc function, I am busy waiting until it is a specific thread's turn. I want to know how to use semaphores in order to make all the threads go to sleep and waking up a thread only when it is its turn to execute to improve efficiency.
int turn = 1;
int counter = 0;
int t, n;
struct tData {
int me;
int next;
};
void *tFunc(void *arg) {
struct tData *data;
data = (struct tData *) arg;
for (int i = 0; i < n; i++) {
while (turn != data->me) {
}
counter++;
turn = data->next;
}
}
int main (int argc, char *argv[]) {
t = atoi(argv[1]);
n = atoi(argv[2]);
struct tData td[t];
pthread_t threads[t];
int rc;
for (int i = 1; i <= t; i++) {
if (i == t) {
td[i].me = i;
td[i].next = 1;
}
else {
td[i].me = i;
td[i].next = i + 1;
}
rc = pthread_create(&threads[i], NULL, tFunc, (void *)&td[i]);
if (rc) {
cout << "Error: Unable to create thread, " << rc << endl;
exit(-1);
}
}
for (int i = 1; i <= t; i++) {
pthread_join(threads[i], NULL);
}
pthread_exit(NULL);
}
Uses mutexes and condition variables. Here's a working example:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
int turn = 1;
int counter = 0;
int t, n;
struct tData {
int me;
int next;
};
pthread_mutex_t mutex;
pthread_cond_t cond;
void *tFunc(void *arg)
{
struct tData *data;
data = (struct tData *) arg;
pthread_mutex_lock(&mutex);
for (int i = 0; i < n; i++)
{
while (turn != data->me)
pthread_cond_wait(&cond, &mutex);
counter++;
turn = data->next;
printf("%d goes (turn %d of %d), %d next\n", data->me, i+1, n, turn);
pthread_cond_broadcast(&cond);
}
pthread_mutex_unlock(&mutex);
}
int main (int argc, char *argv[]) {
t = atoi(argv[1]);
n = atoi(argv[2]);
struct tData td[t + 1];
pthread_t threads[t + 1];
int rc;
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
for (int i = 1; i <= t; i++)
{
td[i].me = i;
if (i == t)
td[i].next = 1;
else
td[i].next = i + 1;
rc = pthread_create(&threads[i], NULL, tFunc, (void *)&td[i]);
if (rc)
{
printf("Error: Unable to create thread: %d\n", rc);
exit(-1);
}
}
void *ret;
for (int i = 1; i <= t; i++)
pthread_join(threads[i], &ret);
}
Use N+1 semaphores. On startup, thread i waits on semaphore i. When woken up it "takes a turnand signals semaphorei + 1`.
The main thread spawns the N, threads, signals semaphore 0 and waits on semaphore N.
Pseudo code:
sem s[N+1];
thread_proc (i):
repeat N:
wait (s [i])
do_work ()
signal (s [i+1])
main():
for i in 0 .. N:
spawn (thread_proc, i)
repeat N:
signal (s [0]);
wait (s [N]);
Have one semaphore per thread. Have each thread wait on its semaphore, retrying if sem_wait returns EINTR. Once it's done with its work, have it post to the next thread's semaphore. This avoids the "thundering herd" behaviour of David's solution by waking only one thread at a time.
Also notice that, since your semaphores will never have a value larger than one, you can use a pthread_mutex_t for this.

Thread syncronization to print 5 random numbers

I'm asked to write a program that will have 2 threads and print 5 random integers such that the first thread will generate a number, the second will print it. Then the first will generate the 2nd number, the second thread will print it... etc. using a mutex.
My code now execute it for one cycle. How can I extend it to make threads excute the methods 5 times?
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
void* generate (void*);
void* print (void*);
pthread_mutex_t m;
int number = 5;
int genNumber;
int main()
{
int i;
srandom(getpid());
pthread_t th[2];
pthread_mutex_init(&m,NULL);
pthread_create(&th[0],NULL,generate,NULL);
pthread_create(&th[1],NULL,print, NULL);
for (i = 0; i < 2; i++)
pthread_join(th[i], NULL);
pthread_mutex_destroy(&m);
return 0;
}
void* generate(void* arg)
{
pthread_mutex_lock(&m);
genNumber = random() % 9;
printf("Generated #1 \n");
pthread_mutex_unlock(&m);
}
void* print(void* arg)
{
pthread_mutex_lock(&m);
printf("The number is %d " , genNumber);
pthread_mutex_unlock(&m);
pthread_exit(NULL);
}
Use condition variables to synchronize the two threads. When a thread has completed its work, it signals to the other thread to wake up, and then it goes to sleep to wait for more work. So something like this:
// Pseudocode
pthread_cond_t c1, c2;
pthread_mutex_t mutex;
// Thread 1 (producer):
for(int i = 0; i < 5; i++)
{
lock(mutex);
genNumber = random() % 9;
signal(c2);
wait(c1, mutex);
unlock(mutex);
}
// Thread 2 (consumer):
for(int i = 0; i < 5; i++)
{
lock(mutex);
wait(c2, mutex);
print("The number is %d\n", genNumber);
signal(c1);
unlock(mutex);
}
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<unistd.h>
static int *generate(void *);
static int *print(void *);
pthread_mutex_t m;
pthread_cond_t con;
int munmber=10;
int gennumber;
int main() {
srandom(getpid());
pthread_t th1,th2;
pthread_mutex_init(&m,NULL);
pthread_create(&th2,NULL,print,NULL);
sleep(1);
pthread_create(&th1,NULL,generate,NULL);
pthread_join(th1,NULL);
pthread_join(th2,NULL);
pthread_mutex_destroy(&m);
}
static int *generate(void *arg) {
int i;
while(i<5) {
pthread_mutex_lock(&m);
gennumber=random()%8;
printf("NUMMBER GENERATED.... \n");
pthread_cond_signal(&cond);
i++;
pthread_mutex_unlock(&m);
sleep(2);
if(i==5)
exit(1);
}
return 0;
}
static int *print(void *arg) {
int i;
while('a') {
pthread_cond_wait(&cond,&m);
printf("GENERATED NUMBER is %d\n",gennumber);
i++;
pthread_mutex_unlock(&m);
}
return 0;
}
A mutex is not sufficient here. You will need a condition variable to make sure that the numbers are printed in the correct order. Some pseudocode:
//producer thread:
for(int i = 0; i < 5; i++)
{
number = random();
signal the other thread with pthread_cond_signal
wait for signal from the consumer
}
// consumer thread
for(int i = 0; i < 5; i++)
{
wait for signal with pthread_cond_wait
print number
signal the producer to produce another number
}
You can do it like this:
int* generated = null;
void generate() {
int i = 0;
while (i<5) {
pthread_mutex_lock(&m);
if (generated == null) {
generated = malloc(int);
*generated = random() % 9;
printf("Generated #1 \n");
++i;
}
pthread_mutex_unlock(&m);
}
pthread_exit(NULL);
}
void print() {
int i = 0;
while (i<5) {
pthread_mutex_lock(&m);
if (generated != null) {
printf("The number is %d " , generated);
free(generated);
generated=null;
}
pthread_mutex_unlock(&m);
}
pthread_exit(NULL);
}
Actually I did write it without a compiler so there can be some errors but the concept should work.